-
Notifications
You must be signed in to change notification settings - Fork 601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce gc allocations on render loop #792
Conversation
Change list:
As for boxing I used approach mentioned in this StackOverflow question. |
Thanks for profiling the library, your PR is for sure reducing the memory consumption, this is something that will improve for sure the library. It is smart what you did, I was building a new HashSet containing the points in the UI, it seems that the points are allocated twice with my approach, but your approach is using the current HashSet and just removing the points that were not used, in general your alternative seems smarter. About the bad performance you faced, I am also working in a high-performance package, it improves Thanks this is definitely better. |
Those comments summarize the changes I made, thanks again for this PR! |
I have been investigating performance and memory issues on my app recently and mentioned that LiveCharts allocate a lot of single use data on every update. This introduces GC pressure which can be avoided.
I created a test workload to highlight those issues. It has 14x4k LineSeries, 4k FinancialSeries, 150k FinancialSeries and 2 ScatterSeries of 8K points on both. Responsiveness in that setup is really bad. It moves, but has huge lags. Though this story is for another time.
This PR focuses on reducing GC allocation on render loop.
Let's take a look at allocations during render (GC Heap Alloc Ignore Free Stacks). I used PerfView Collect command here, app was already started and data loaded for 10-20 seconds. This highlights what types are being constantly allocated.
As we can see main allocation sources are:
BezierData
RectangleHoverArea
HashSet<ChartPoint>
copy constructorThere is also a tricky case with
float is null
. For some reason JITter doesn't optimize boxing when using launching app using PerfView Run command. This doesn't reproduce on normal start (or at least I can't find evidence). However I need that fix inMotionProperty<T>
keep recorded performance data clear. JITter should treatstatic readonly bool
fields as constants at IL->Asm compilation and simplify comparison.