SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and now iOS Charting & Android Chart Components

Welcome to the SciChart Community Forums!

Please use the forums below to ask questions about SciChart. Take a moment to read our Question asking guidelines on how to ask a good question and our support policy. We also have a tag=SciChart on Stackoverflow.com where you can earn rep for your questions!

Please note: SciChart team will only answer questions from customers with active support subscriptions. Expired support questions will be ignored. If your support status shows incorrectly, contact us and we will be glad to help.

Answered
0
0

Hi

 

I’ve been developing an application which monitors parameters such as pressure and temperature in real time over serial communications. The data is displayed with SciChart in realtime, the user can configure what is displayed, change the time periods being viewed and the sample time amongst other settings.

 

The performance problem I’m experiencing appears to be from the drawing to SciChartSurface. I have tried a number of different approaches though I’m not sure I’m using the most efficient.

 

I have 5 FastLineRenderableSeries and 5 corresponding IDataSeries<DateTime, double> with the DateTime used as the x axis. The serial comms running separately is on a cycle time of approximately 100mS. The sample time for data appended to the data series can be set between 0.5 and 2 seconds.

 

As a means to monitor the performance of the application I have a separate serial comms application running on a different computer listening and displaying the data, from this data streaming on the screen it is easy to see when the performance is slowing.

 

Initially I had the series scrolling from left to right with all new data causing the x axis VisibleRange to be recalculated. This gives a scrolling effect with the whole chart shifting to the left but concerned the VisibleRange recalculation was causing too much of a processing overhead I changed it. Now data starts from the center of the x axis and only recalculates the x axis VisibleRange when the series reaches the far right of the graph similar to the ECG example.

 

The results were the same every time data was appended without any x axis VisibleRange recalculated there would be a pregnant pause on the serial data around 400mS (this is proportional to the length of time running and number of series being displayed).

 

I also set it up to use FIFO series although I don’t want to lose data I thought I’d try it. This obviously just restricts the performance hit by limiting the buffer size and is not practical unless using an exceptionally small FIFO size.

 

Not sure whether it was the appending or drawing process I allowed the two to be separated. Allowing the user to stop when data is appended and manually trigger when a redraw is performed with InvalidateElement().

 

Initially I let the application run for a minute to store some data then prevented the addition of any more data. It was then evident triggering when a redraw was performed would cause the slowing of serial data.

 

Additionally I have tried the other performance tips and tricks with little effect. If this is the best configuration I will have to open up the sample time to 2 seconds and limit the buffer size using FIFO series as the application could be running for days at a time.

Many Thanks

Miles

  • You must to post comments
Best Answer
1
0

Hi Miles,

Let me try to answer some of these queries for you:

Batching appends – could not implement this (no examples I could make sense of).

Ok, most of the examples use this method. All you need to do is to call this API with an array of many points:

dataSeries.Append(IEnumerable<double> xData, IEnumerable<double> yData);

rather than this one repeatedly in a loop:

dataSeries.Append(double singleXValue, double singleYValue);

Inside the DataSeries.Append() call is a calculation to determine min, max, perform bounds checks etc… If you append an array with several points instead of point by point, you will see orders of magnitude speed improvements.

In particular take a look at the Performance Demo – this uses a buffer of 1000 points to append in batches, and is able to append hundreds of thousands of points per second because of this.

Another performance difference I’m noticing when I open the example project compile and run it the whole execution seems extremely slow where as if I run the example “Launch SciChart WPF Examples” from the installed link under Start button it seems very fast (particularly ECG Monitor, Oscilloscope and Spectrum Analyzer).

This is probably because you are compiling the WPF Examples in Debug mode or running with the debugger attached. SciChart outputs all sorts of debug information, and the CLR also appends debug symbols. Compiling and running in Release mode without the debugger attached will give you a performance improvement of 100-200%. Please re-try in release and without the debugger attached. If you still notice a difference in performance, let me know.

Although the large example project is an excellent way to help show its use I struggle to get my head round some of the MVVM examples. A combination of examples especially like the simplest ones used in MSDN Help used to demonstrate the basics of the class, method, property is ideal.

Unfortunately a chart control is a complex piece of API. There is no easy way to break this down into class by class, line by line like the MSDN docs do for the .NET framework. Similarly MVVM is a complex concept which really requires study in of itself. We try our best to present examples with single feature but even those require many parts, such as Data, RenderableSeries and Axes. For those that require API documentation there is a CHM file included with the trial download, and if you link against SciChart.dll in your install directory, you should see the API documentation in Intellisense as you type.

Let me know if you are able to implement Batch appends using the API above, and if that made a difference to performance.

Best regards,
Andrew

  • milesm
    Hi AndrewThanks for the reply and apologies on my part, I’ve determined my bottleneck problem is due to the Debug mode.I had used Release when deploying and had question the fact it seem to be without any speed issues but had used Debug with the debugger attached when developing at my desk. I should have determined that earlier on.In release mode there is no obvious performance issue even after an hour running :)Now on to put some Annotation... Many Thanks Miles
  • Andrew
    Hi Miles,Absolutely no problem and I'm glad to be of help. I hope this discussion will be helpful to other developers of SciChart also.So the problem was simply Debug mode not Release? Strange - but it does happen.Anyway, glad you got it sorted and good luck with your project!Best regards, Andrew
  • You must to post comments
1
0

Hi Miles,

Ok, sounds to me like you have a complex scenario and debugging the performance requires us to see some code. Is there any way you can get over to us a solution to reproduce the issues you are experiencing?

You say you’ve read the performance tips & tricks, so i assume you are doing, or have tried some of the following? Is there anything in this list which rings an alarm bell?

  • Batching updates using SciChartSurface.SuspendUpdates(), or DataSeriesSet.SuspendUpdates()
  • Batching appends by using DataSeries.Append(IEnumerable) as opposed to DataSeries.Append(x,y) – single points. Note here appending arrays is by far the fastest rather than Lists or IEnumerable LINQ results
  • Ensure StrokeThickness is 1, tried setting antialias off
  • Ensure you are minimising calls to Insert or Remove from DataSeries (particularly inserts as this triggers memory copy on the entire array for each point inserted)
  • Tried using SciChartSurface.RenderPriority = RenderPriority.Low as this puts draw priority below mouse input

Best regards,
Andrew

  • milesm
    Hi AndrewThanks for the reply and sorry for my delayed response. I can send the project though it would be difficult to simulate the issue I’m seeing as it is relying on serial comms hardware. Let me know if it’s worth emailing the project and I will.I’ve been messing with it to try and improve and address possible points you’ve mentioned • Batch updates - already using SuspendUpdates(). • Batching appends – could not implement this (no examples I could make sense of). • Stroke Thickness – originally set at 1 but client requested to increase the thickness of the line as it wasn’t very legible using a thickness of 1. • Minimise Insert and Remove – not being used. • RenderPriority = RenderPriority.Low – may have improved responsiveness a little.The Batch appends mentioned in the “Performance Tips and Tricks” has a syntax error or maybe I’m missing a reference but I couldn’t get that text to compile. The one place where AddRange is used in the example project did not help me.Although the large example project is an excellent way to help show its use I struggle to get my head round some of the MVVM examples. A combination of examples especially like the simplest ones used in MSDN Help used to demonstrate the basics of the class, method, property is ideal.I’ve broken down the application so I can isolate various aspects and try and determine my bottleneck. I have a stop watch implemented to capture the loop time and maximum loop time of the application, every time data is appended or the graph redraws I can then quantify the time taken. I have done this for 1, 2 and three series and for just over a 1000 points.The results give an average time of 400 uS per point this would be the same for 1, 2 or 3 series. - For 2 series of 500 points each giving a total of 1000 points is around 0.4 mS on top of the normal loop time. - For 1 series of 1000 points gives 0.4 mS on top of the normal loop time.If I’m appending data every second, 1 series accumulating data for nearly 17mins gives a 1000 points. Turn on 4 series for an hour will give around 16000 points which translates to over 5 seconds. As the sample time is now shorter than the time to redraw it makes it unusable.A key test allows a number of points to have been appended after which any further data appends are not made this allows a normal loop time of around 100mS. I can then manually trigger a redraw with InvalidateElement() which gives the same time per point. This test would eliminate any append performance hit as it is pure a redraw of the existing data (I’m not sure what goes on inside InvalidateElement() so may be wrong).Another performance difference I’m noticing when I open the example project compile and run it the whole execution seems extremely slow where as if I run the example “Launch SciChart WPF Examples” from the installed link under Start button it seems very fast (particularly ECG Monitor, Oscilloscope and Spectrum Analyzer).Many Thanks Miles
  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.