Thanks for your detailed reply. I’ve a few comments.
Just to give an idea of our goals –> our target is to have 48 charts on a single screen (3 charts per unit with a max of 16 units per screen). Each unit updates at ~250pts / second and we’ll show 8 seconds worth of data (ie. ~2000 pts/chart).
Now, about your first point of 3 charts for every chart due to overlay:
First, the overlays that I do have in my sample have the ChartsVisibility property set to Collapsed, so the SciChart surface shouldn’t actually be rendering those, should they? This means for 10 charts, I only have 10 charts rendered, not 30. Of course they are updating the overlay data to get the FPS, but I would hope the collapsed charts do not to affect anything.
Second, even when the whole Overlay is Collapsed, the slowdown occurs. I assume the very existence of the overlays is hooking into the CompositionTarget.Rendering, as you’ve described, even when Collapsed. This, combined with the point above, is making these Overlays expensive.
I did find this question from 2 years ago:
“We’re still investigating why this is, but we believe there is some contention between the rendering (UI) thread and the appending (DataSeries.Append) thread.”
So it’s possible that the overlay is doing DataSeries.Append regardless of if the actual chart is visible or not.
To try to get around this issue but also get an idea of SciChart FPS vs Composition FPS, I tried to add a single SciChartPerformanceOverlay in the code behind and have it attach to only the first ChartControl. Unfortunately, it doesn’t seem to pick up the TargetSurface properly. I can see the CompositionTaget and the Chart Stats (point count) properly, but the SciChartSurface is always infinite.
The code I’m using is this:
private static object _overlaySyncLock = new object();
private static bool _overlayCreated = false;
private void UserControl_Loaded(object sender, RoutedEventArgs e)
SciChartPerformanceOverlay overlay = new SciChartPerformanceOverlay()
ChartsVisibility = Visibility.Collapsed,
TargetSurface = sciChartSurface, // <– Is this correct?
Margin = new Thickness(4),
Background = Brushes.Black,
Foreground = Brushes.AliceBlue
GridForOverlay.Children.Add(overlay); // This is an empty grid that positions the overlay where I'd like
_overlayCreated = true;
Am I doing something wrong here?
Re: Update, it seems like the charts of the overlay are not at fault and it's actually the TextBlock rendering the FPS. Is there any way to set the update speed of the Overlay? If it updated a few times a second or less, that'd be fine for diagnostics and should remove this bottleneck. A MaxFrameRate like the SciChartSurface might be useful. Just a thought.
Now, all that being said, if I remove the overlays it does improve performance but then if I increase the number of charts, the stuttering does come back. I did find that setting RenderPriority to Normal from Low makes this better, but a comment elsewhere in these forums said Low is better to keep UI snappy. What do you think?
I'm also wondering why it is that the mouse movement is what causes the stuttering at all, even without mouse events or modifiers? Can you shed some light on why the mouse movement is a trigger for stuttering?
Finally, the part that puzzles me most is that when the Overlays are there, the SciChartSurface FPS is much lower than the CompositionTarget. The frame rate is much lower than the expected MaxFrameRate of 30. Is there something else throttling it to less than MaxFrameRate?
Sorry for the long reply. I'm enjoying the ease of SciChart API's and want to figure out/understand this last performance item.
Thanks for all the help! It's very insightful!
Hi Brian: “ChartsVisibility property set to Collapsed, so the SciChart surface shouldn’t actually be rendering those” If you look at the profiling results it says otherwise. The time is spent actually updating the TextBlock label inside SciChartPerformanceOverlay. In my profiling there is a 60:1 overhead of adding a SciChartPerformanceOverlay to each chart in your application. Please remove them and see if you reproduce my results.
(2nd reply to make it easier to read!) If you want to record performance without impacting performance the best way to do this is to subscribe to SciChartSurface.Rendered event, log the time, and display the FPS=1/MovingAverageOf(Time) in a TextBlock. Can you do this? Without SciChartPerformanceOverlay which seems to (ironically) introduce a performance problem.
(3rd reply to make it easier to read!) SciChart’s FPS is often lower than CompositionTarget.Rendering FPS because we don’t render using WPF. We actually use CompositionTarget.Rendering as a trigger to start the draw process, but we don’t draw on every single CompositionTarget.Rendering. CT.Rendering is a complex event which actually speeds UP the more you move the mouse, the more you trigger layout or if you change visual elements. It can vary from 60FPS (Normal) right up to 500FPS (when rapidly updating a WPF UI). This is why we must decouple from it. SciChart renders ‘as fast as it can’ without locking up the UI. The RenderPriority.Low option helps in some edge cases. MaxFrameRate also helps in some edge cases, but it can also hamper performance in some edge cases. Didn’t I say performance of charting was complex? :)
Finally, if you remove the SCPerf Overlay and still experience perf problems feel free to send over a new sample (or new instructions to use the sample) to reproduce performance problems this side and we can continue to investigate. Best regards,
Hi Andrew – not sure if you’re still following this thread or not. I’m replying to your Answer in the hopes it sends you a notification that there’s activity here. See my answer below for updates and queries. Thanks!