WPF Charting Documentation - SciChart WPF Charts SDK v5.x
Performance Tips & Tricks

While we believe SciChart is pretty performant out of the box, you can do a few things to make CPU cycles go that extra bit further. With the following tips enabled it is possible to render many tens of millions of points at interactive framerates with SciChart.

IMPORTANT! Ensure Data is Sorted in the X-Direction

The number one fundamental for high performance in SciChart is to ensure that data is sorted in the X-Direction increasing. As of SciChart 3.0 and above, this is not mandatory, but several key algorithms such as HitTest, Indexing and Resampling require that data is sorted in the X-Direction for optimum performance. With unsorted data, SciChart will still render, but it will do so using vastly inferior algorithms. The difference is tens of millions of points with sorted X-Data and a few hundred thousand without. We recommend if you can, sort.

To enable unsorted data

SciChart will throw an exception if you append unsorted data to a DataSeries. This is intended to warn you and prevent unintaltional appending of unsorted data to a DataSeries.

http://support.scichart.com/__swift/apps/base/javascript/__global/thirdparty/TinyMCE/plugins/moxiemanager/data/files/thumb/t_AcceptsUnsortedDataException_lrg.PNGSince unsorted data is so catastrophic to performance, in SciChart v4 we now throw an InvalidOperationException if you append or insert data which causes the data-series to be unsorted in the X-Direction. If you upgrade to SciChart v4 and see this exception, and you intend to have unsorted data in a data-series, you can disable the error by setting the following property:

To enable unsorted data
Copy Code
// Disables exception on append unsorted data
// Please note, data unsorted in X is bad for // performance of large datasets. Don't do it // unless you need to!
DataSeries.AcceptsSortedData = true;

 

Batch Appends to the DataSeries, using the overloaded API

Batching appends using the overloaded API to append IEnumerable, IList or Arrays has a massive impact on DataSeries performance. Arrays have the biggest impact as these can be indexed using unsafe code. If you have a lot of data to append, create a small buffer (say 10-100 points) and append them in blocks.

Batch Appends to the DataSeries, using the overloaded API
Copy Code
double [] xBuffer = new double[100];
double [] yBuffer = new double[100];

for(int i = 0; i < 100; i++)
{
   xBuffer[i] = GetNextXValue(i);
   yBuffer[i] = GetNextYValue(i);
}

// Single recalculation of Min, Max and Single
// redraw call is executed when appending a block
// Appending arrays is much faster than IEnumerables
dataSeries.Append(xBuffer, yBuffer);

NOTE: Why does this work? When data is appended in blocks, you get a single draw call at the end. You also reduce thread-contention if you are appending on a background thread and drawing on the UI thread. Finally, the above is simply more memory efficient as we only need to recalculate the additional memory required once, rather than per-point appended.

Batch updates inside a SciChartSurface.SuspendUpdates() using block

When performing multiple updates, such as VisibleRange changes, DataSeries changes and RenderableSeries or Axis Property changes, each change can potentially trigger a redraw in SciChart. To prevent this, use the methods from the ISuspendable implementation on SciChartSurface.

Batch updates inside a SciChartSurface.SuspendUpdates() using block
Copy Code
using (sciChartSurface.SuspendUpdates())
{
    dataSeries.Append(x1, y1);
    dataSeries.Append(x2, y2);
    dataSeries.Append(x3, y4);
    sciChartSurface.YAxis.VisibleRange = new DoubleRange(200, 300);
    sciChartSurface.XAxis.VisibleRange = new DoubleRange(-10, 10);
} // Single redraw call is executed on exit of using block

Setting RenderPriority

By default, SciChart throttles rendering so it only draws when necessary, as opposed to every property or data change. The default throttling results in approximately 60FPS (Frames per second).

The SciChartSurface.RenderPriority property may be used to lower the priority of rendering to below that of Mouse and Input in WPF. This is an extremely useful property if you are experiencing a hanging UI or stutter in the user interface, because when this happens it means the WPF Message Loop (UI Thread) is starved and is unable to process events.

To change the render priority, please use the following code. In extremely high CPU scenarios, or when running SciChart on a notebook or computer with slow CPU then this property can have the biggest change to responsiveness of the chart.

Setting RenderPriority
Copy Code
var sciChartSurface = new SciChartSurface();
sciChartSurface.RenderPriority = RenderPriority.Low;

Or,

Setting RenderPriority
Copy Code
<SciChartSurface RenderPriority="Low"/>

Limiting Framerate

An alternative to SciChartSurface.RenderPriority is to set SciChartSurface.MaxFrameRate. Lower framerates will reduce the number of times SciChart attempts to draw per second.

Limiting Framerate
Copy Code
var sciChartSurface = new SciChartSurface();
sciChartSurface.MaxFrameRate = 24;

Or,

Limiting Framerate
Copy Code
<SciChartSurface MaxFrameRate="24"

NOTE: To reset MaxFrameRate, set it to null.

Use the DirectX Renderer (Direct3D11RenderSurface)

Whiel this may seem a shameless plug to upgrade to SciChart Enterprise edition which includes the Direct3D11RenderSurface, if you are concerned about performance, you should be using the DirectX renderer plugin.

The DirectX Rneder Surface is significantly faster (on average 3.92x faster) than software renderers in many cases. For a performance comparison, please see the article http://www.scichart.com/how-fast-is-scichart-wpf-chart.

DirectX is on average 3.92x faster than softwar rendering. Some cases are up to 40x faster!

NOTE: Since this article was written we have now vastly improved DirectX scatter performance and blasted these numbers out of the water. See http://www.scichart.com/directx-scatter-chart-performance-fixed for details. This means that SciChart’s DirectX is now faster than software rendering in all cases.

Check your Computer’s Power Management Options

By default, the Balanced Power Plan in Windows (see Control Panel > Power Options) includes CPU throttling. This is designed to reduce power usage when the CPU is not being heavily loaded, or, is overheating.

Minimum Processor State < 100% means CPU Throttling is enabled

Because SciChart uses throttling and does not continually enage the CPU, this can trick the operating system into thinking it’s not very busy, causing the CPU to be throttled down e.g. run at a lower clock frequency or with higher latency. We have noticed considerable performance gains and resolution of stutter on some PC’s by disabling CPU throttling on the target OS.

StrokeThickness = 1 is Faster

NOTE: This hint only affects the software renderers.

Drawing more pixels = using more CPU. Setting StrokeThickness to 1 can result in higher performance by lowering stress on the the software renderers.

Switch Off AntiAliasing

NOTE: This hint only affects the software renderers.

Drawing alpha blended anti-aliased lines = using more CPU. Setting AntiAlias = false can result in higher performance by lowering stress on the the software renderers.

Use SolidColorBrush not LinearGradientBrush

NOTE: This hint only affects the software renderers

The FastMountainRenderableSeries, FastColumnRenderableSeries, FastCandlestickRenderableSeries types all support LinearGradientBrush fills as well as SolidColorBrush. Internally, these are implemented using a fast-caching texture engine, however, solid colors are a lot faster than gradient fills. Where possible, if performance is absolutely necessary, use solid colors for fills instead of gradient brushes.

Ensure ResamplingModes are used

By default, SciChart uses resampling (culling) of data to ensure the minimum viable dataset is displayed on the screen. Resampling is intended to be lossless, and automatic.

If you disable resampling (setting BaseRenderableSeries.ResamplingMode = None) you will experience a degredation in performance. This is more pronounced in the software (non DirectX) renderers.

Keep up-to-date with the Latest SciChart Version

You will see in the image in Use the DirectX Renderer (Direct3D10RenderSurface)  comparing performance of SciChart versions that v1 to v2 to v3 to v3.2 with DirectX to v4 with DirectX shows significant performance increases with time. This is because we are always working on improving performance of the overall charting engine.

Staying up to date helps to ensure you have the latest algorithms and optimizations for fast, efficient charting with SciChart.

PointMarkers and Scatter Series are Slower than Line Series

NOTE: This hint only affects the software renderers

For Scatter series and Line Series with PointMarkers, note the total point count will be lower than just for lines. This is because point-marker points require additional CPU to render. To minimise this effect, there are two things you could do:

PointMarkers and Scatter Series are Slower than Line Series
Copy Code
// Dynamically showing or hiding PointMarkers based on zoom level
var xAxis = sciChartSurface.XAxis;
xAxis.VisibleRangeChanged += (s,e) =>
{
    double xRangeDifference = xAxis.VisibleRangeChanged.AsDoubleRange().Diff;
    if (xRangeDifference > 100) // or arbitrary threshold value
    {
        sciChartSurface.RenderableSeries[0].PointMarker = null;
    }
    else
    {
        sciChartSurface.RenderableSeries[0].PointMarker = new EllipsePointMarker()
        {
            Width = 5,
            Height = 5,
            Fill = Colors.Blue
        };
    }
}

Dynamically Toggle Annotations if UIElement Annotations are slow

SciChart uses a Raster-based (Bitmap/Texture) rendering for all line series, however annotations are provided by WPF UIElements. UIElements (and sadly WPF) are not capable of high performance when thousands of elements are drawn, hence restricting the count of annotations is imperative to keeping performance up.

When drawing annotations, if possible, restrict the number of annotations on the chart at any one time to a few thousand. Again you can use a similar Level of Detail technique as that suggested above - when zooming out (handle XAxis.VisibleRangeChanged), you may hide the annotations (by swapping the entire SciChartSurface.Annotations collection with another AnnotationCollection).

Dynamically Toggle Annotations if UIElement Annotations are slow
Copy Code
// Dynamically showing or hiding annotations based on zoom level
var xAxis = sciChartSurface.XAxis;
xAxis.VisibleRangeChanged += (s,e) =>
{
    double xRangeDifference = xAxis.VisibleRange.AsDoubleRange().Diff;
    if (xRangeDifference > 100) // or arbitrary threshold value
    {
        // Store and turn off all annotations
        this.savedAnnotations = sciChartSurface.Annotations;
        sciChartSurface.Annotations = new AnnotationCollection();
    }
    else
    {
        // Restore annotations
        sciChartSurface.Annotations = this.savedAnnotations;
    }
};

Batch Add Annotations if UIElement Annotations are Slow

When appending lots of annotaitons you will notice WPF really slows down and is unable to cope with more than a few thousand annotations.

If you need to append a large amount of annotations to a SciChartSurface, we recommend manipulating a new AnnotationCollection and attaching the whole collection to the chart, as opposed to manipulating the SciChartSurface.Annotations collection one by one.

Batch Add Annotations if UIElement Annotations are Slow
Copy Code
using (sciChartSurface.SuspendUpdates())
{
  // Create temporary AnnotationCollection
  var myAnnotations = new AnnotationCollection();

  double minx = double.MaxValue;
  double maxx = double.MinValue;

  for (int i = 0; i < 1000; i++)
  {
    var a = new BoxAnnotation
    {
      // Assign X1,Y1, Background etc...
    };

     myAnnotations.Add(a);
  }

  // Reassign annotation collection
  sciChartSurface.Annotations = myAnnotations;
  sciChartSurface.ZoomExtents();
}

Replace Annotations with Custom Drawing

Annotations provide a rich, useful API for overlaying markers onto the chart. If you require tens or hundreds of thousands of visual markers, annotations performance will be a hindrance. In this case, we often recommend using a scatter chart with a custom point marker. You can find info about our PointMarkers API in PointMarker API – BaseRenderableSeries.Pointmarker

 

See Also

 

 


SCICHART ® is a Registered Trademark in the UK, US and EU. Copyright SciChart Ltd 2011-2018.

Email us to give feedback!