You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SE is based on the graph flow engine and adds branching on top of it. This results in big data structures for complicated code. We should investigate the hotspots here and add caching for our immutable types that represent the same state.
Rethink ProgramState.AddVisit: The add operation allocates a lot (10% in terms of object count and MB of the overall allocations including the analyzer runner and the Roslyn analysis) of System.Collections.Immutable.SortedInt32KeyNode<> (Options: precompute the dictionary and use a mutable dictionary instead. We can remove the visit tracking from ProgramState and move it to a local in "Execute" instead or make it mutable in ProgramState. Either would also avoid new copies of ProgramState. Doesn't work due to the way visit count works.) Potential savings by removal of VisitCount: SortedInt32KeyNode down from 75.324 to 56.054 number of objects (down to 75%). Overall: 96,5% after removal (number of objects and MB)
Change the return type of PreProcess, OperationDispatcher.Process, and PostProcess from SymbolicContext[] to readonly struct SymbolicContexts(SymbolicContext first, SymbolicContext second, SymbolicContext[] others). This would pass SymbolicValue via the stack instead of the heap (Potential savings: NoOfObjects: SymbolicValue[]: 17.221, List<SymbolicValue> 10.000 ~4% of the total; 1.000.000 byte in total). Background: We almost always return 0, 1, or 2 states but never more than that at the moment. With the SymbolicContexts we would reserve space on the stack for up to two states and any additional states would be passed via the others array. The SymbolicContexts would implement the enumerable pattern (also as a struct) so we can foreach over it (but I would not implement IEnumerable, so we don't Linq over it by accident). SE: Pass states per stack #7059
There are a lot of state machine instances created by yield return in ProcessBranching and ProcessOperation. We may consider moving to some stack-based solution if possible.
SonarAnalyzer.CFG.Roslyn types (e.g. ControlFlowGraph). Measure allocations and consider turning them into readonly structs
SonarAnalyzer.CFG.Roslyn types Use compiled expressions like with LightupHelpers.CreateSyntaxPropertyAccessor to avoid the overhead of PropertyInfo.GetValue.
SE is based on the graph flow engine and adds branching on top of it. This results in big data structures for complicated code. We should investigate the hotspots here and add caching for our immutable types that represent the same state.
SymbolicValue.This
#6980precompute the dictionary and use a mutable dictionary instead. We can remove the visit tracking from ProgramState and move it to a local in "Execute" instead or make it mutable in ProgramState. Either would also avoid new copies of ProgramState.Doesn't work due to the way visit count works.) Potential savings by removal of VisitCount: SortedInt32KeyNode down from 75.324 to 56.054 number of objects (down to 75%). Overall: 96,5% after removal (number of objects and MB)PreProcess
,OperationDispatcher.Process
, andPostProcess
fromSymbolicContext[]
toreadonly struct SymbolicContexts(SymbolicContext first, SymbolicContext second, SymbolicContext[] others)
. This would pass SymbolicValue via the stack instead of the heap (Potential savings: NoOfObjects:SymbolicValue[]
: 17.221,List<SymbolicValue>
10.000 ~4% of the total; 1.000.000 byte in total). Background: We almost always return 0, 1, or 2 states but never more than that at the moment. With the SymbolicContexts we would reserve space on the stack for up to two states and any additional states would be passed via theothers
array. The SymbolicContexts would implement the enumerable pattern (also as a struct) so we can foreach over it (but I would not implement IEnumerable, so we don't Linq over it by accident). SE: Pass states per stack #7059yield return
in ProcessBranching and ProcessOperation. We may consider moving to some stack-based solution if possible.LightupHelpers.CreateSyntaxPropertyAccessor
to avoid the overhead ofPropertyInfo.GetValue
.The text was updated successfully, but these errors were encountered: