Hello,
we are building an application where Charts are created/placed by the user in a form of editor.
We observed that the creation of the first Chart takes between 1 to 3 seconds (depending on the system) but the creation of subsequent Charts takes virtually no time (as it should be).
We assume that the creation of the first Chart involves some kind of time consuming initialization that is later used in the creation of subsequent Charts.
So we have researched if there is a way to do this initialization at the start of our application, so the user is not inconvenienced by a three second waiting time while placing the first Chart.
We discovered the “LoadLibrariesAndLicenseAsync”-function. However, it looks like it has no measurable effect.
Maybe we are using it wrong?
Here is an example code to illustrate the problem in a condensed manner:
Two charts are created and each time the time it takes to create them is measured.
The first creation takes about 1600 milliseconds, the second one only 2.
How can we make both creations only take a few milliseconds?
Thank you.
// SciChartSurface.SetRuntimeLicenseKey("our key");
await SciChart.Charting.Visuals.SciChart2DInitializer.LoadLibrariesAndLicenseAsync(
"our key",
null); //...does not seem to work
Stopwatch sw = new Stopwatch();
sw.Restart();//start stopwatch
//creating the first Scichart with test data:
SciChartSurface sciChartSurface = new SciChartSurface();
XyDataSeries<double, double> xyDataSeries = new XyDataSeries<double, double>();
xyDataSeries.AcceptsUnsortedData = true;
FastLineRenderableSeries fastLineRenderableSeries = new FastLineRenderableSeries();
fastLineRenderableSeries.DataSeries = xyDataSeries;
sciChartSurface.RenderableSeries.Add(fastLineRenderableSeries);
NumericAxis m_xAxis = new NumericAxis();
NumericAxis m_yAxis = new NumericAxis();
m_yAxis.AutoRange = AutoRange.Always;
sciChartSurface.XAxis = m_xAxis;
sciChartSurface.YAxis = m_yAxis;
using (xyDataSeries.SuspendUpdates())
{
for (int i = 0; i < 100; i++)
xyDataSeries.Append(i, Math.Sin(i));
}
Screen.Children.Add(sciChartSurface);//add first Scichart to grid
sciChartSurface.Margin = new Thickness(0, 0, 500, 0);
MessageBox.Show("time: "+sw.ElapsedMilliseconds); ////////// 1610 Mlliseconds
sw.Restart();//restart stopwatch
//creating the second Scichart with test data:
SciChartSurface sciChartSurface2 = new SciChartSurface();
XyDataSeries<double, double> xyDataSeries2 = new XyDataSeries<double, double>();
xyDataSeries2.AcceptsUnsortedData = true;
FastLineRenderableSeries fastLineRenderableSeries2 = new FastLineRenderableSeries();
fastLineRenderableSeries2.DataSeries = xyDataSeries2;
sciChartSurface2.RenderableSeries.Add(fastLineRenderableSeries2);
NumericAxis m_xAxis2 = new NumericAxis();
NumericAxis m_yAxis2 = new NumericAxis();
m_yAxis2.AutoRange = AutoRange.Always;
sciChartSurface2.XAxis = m_xAxis2;
sciChartSurface2.YAxis = m_yAxis2;
using (xyDataSeries2.SuspendUpdates())
{
for (int i = 0; i < 100; i++)
xyDataSeries2.Append(i, Math.Sin(i));
}
Screen.Children.Add(sciChartSurface2);//add second Scichart to grid
sciChartSurface2.Margin = new Thickness(500, 0, 0, 0);
MessageBox.Show("time: "+sw.ElapsedMilliseconds); //////////////////////////// 2 Mlliseconds
- Marc Vahldieck asked 1 year ago
- You must login to post comments
You’ve already tried LoadLibrariesAndLicenseAsync() – that is covered in the video below and should massively improve startup speed.
Here’s an up to date link to the github project
Related forum questions here
https://www.scichart.com/questions/wpf/new-user-slow-load
https://www.scichart.com/questions/wpf/slow-first-time-startup
https://www.scichart.com/questions/wpf/application-hangs-upon-displaying-chart-for-the-first-time
License loading is one of the biggest components of initial startup. It can be done async while your application loads. After that, SciChart WPF has to instantiate the graphics engine (one-time cost) and initialise control templates of the library (loading BAML/XAML which is slow). Once those are done as you’ve noticed subsequent chart startup is fast.
I’ve tested out our AsyncLicenseLoading application above using v7 of SciChart and profiled it. Here’s the breakdown of timings I see:
- 300 milliseconds for async license load (can be hidden behind a splash screen)
- 950 milliseconds for first 2D chart load
- 2ms for second 2D chart load
So I can confirm numbers similar to yours. I decided to profile it and this is what I see in dotTrace for loading a single chart:
- 737ms spent in instantiating the chart itself.
- 400ms of which is finding the optimal GPU adapter.
- Another 140ms spent creating the first rendersurface (initializes the graphics engine)
So there’s room for improvement here.
Maybe we can allow you to do the detection of GPU adapter earlier in splash screen or even skip it altogether if you provide some flags to say what kind of hardware you have.
I’d recommend doing the same test as me – profiling your application startup. It could be you have something else going on there as well such as data creation or instantiation of other controls that are slowing the application startup down.
Best regards
Andrew
- Andrew Burnett-Thompson answered 1 year ago
- last edited 1 year ago
- You must login to post comments
OK Update: You can move the entire GPU Capability Detection into the async initialization thread with this code. Change this in MainWindow.xaml.cs of the Async License Loading test app.
private async void MainWindowLoaded(object sender, RoutedEventArgs e)
{
// Wait for the license initialization we triggered in App.xaml.cs
await SciChart2D3DInitializer.Awaiter.ContinueWith(result =>
{
Stopwatch sw = new Stopwatch();
sw.Restart();
// Important. Turn this off, there's a bug in v7 where we're writing the result to a log file
VisualXcceleratorEngine.WriteWarningsToOutput = false;
// Force a GPU Cap test now
Console.WriteLine("Supports HW Acceleration? " + VisualXcceleratorEngine.SupportsHardwareAcceleration);
MessageBox.Show("Time to do GPU Cap Test? " + sw.ElapsedMilliseconds);
});
// ...
The Console.WriteLine() is irrelevant, we want to call VisualXcceleratorEngine.SupportsHardwareAcceleration async while the application is loading.
This will force the GPU Capability test on startup and shave 50% (400ms) off the first chart startup time.
The remaining time is now initialization of the 3D engine (one time) and other instantiation of the chart. I will talk to the WPF team tomorrow see what else we can do.
Thanks for reporting!
Best regards,
Andrew
- Andrew Burnett-Thompson answered 1 year ago
- You must login to post comments
Hello Andrew,
thank you for your help, I did the things you mentioned and achieved moderate success.
My current solution however is quite simple:
I create SciChart-Elements (one instance of everything that is available in the editor) in a separate thread that starts at the beginning of the program.
When the user reaches the part of the application were he can place SciChart-Objects, everything is already loaded und there is no delay.
However, if there is a more elegant solution, I’m all ears.
- Marc Vahldieck answered 12 months ago
-
Hi Marc, can you share some code how you’ve done this? I wasn’t aware it was possible to create a SciChartSurface on another thread. I guess if you’re just instantiating them and throwing them away it can force initialise the graphics engine. Still discussing with the team possible improvements here. Much of the one-time initialization cost can be moved to an async operation which occurs when application starts up
-
Hello Andrew, I have added my solution as an additional answer. I hope this is sufficient.
- You must login to post comments
Hello Andrew,
I have put the following code in a function that is called if the “Loaded”-Event of the Main-Window of my WPF application is triggered.
Thread var = new Thread(() =>
{
new GraphA();
new GraphB();
});
var.SetApartmentState(ApartmentState.STA);
var.Start();
The Thread is a System.Threading.Thread, GraphA and GraphB are Classes that inherit from UserControl and implement various SciChart-elements.
In the editor, the User can create instances of GraphA and -B without delay once the above thread has finished.
- Marc Vahldieck answered 12 months ago
-
Hello Mark, thank you for sharing your solution. At the moment, it is pretty much all one can do to improve startup perfromance. However, we are working on providing API that will allow for more control over chart initialization and loading.
- You must login to post comments
Please login first to submit.