On this step, we will try to determine the origin of the whole “chart bottleneck” issue using subsystems.
- In the list of calls, drill down the main thread to see the most time-consuming calls.
As you see, the main call that affects the performance is OnPaint that takes 718 ms required to draw the temperature graph.
- Look at the list of subsystems for the OnPaint call.
Smart subsystems show us that most of the time in Chart visualization is taken by System…Charting.SmartLabel.IsSmartLabelCollide.
Moreover, as you can see, a lot of time (almost one second) is consumed by System code. More specifically, by the Collections namespace (to display a label on the chart, .NET needs to read a certain value from the chart’s value collection).
This short analysis shows that we can try disabling labels for the chart (we can make them optional in future app versions). Let’s do it in Visual Studio.
- To disable value labels, for the Series property of our chart, set IsValueShownAsLabel to False.
- After the improvement is made, let’s run the profiling session again and take a look at the snapshot.
Here it is! The overall time of the OnPaint call decreased to insigninficant 142 ms. Chart visualization requires just 78 ms and no workload on the System.Collections namespace at all.
Main contribution into overall app performance is now made by the btnLoad_Click call - the OnClick event handler of our Load Temperature Data button.
- Select the btnLoad_Click call in the list.
Again, just a quick glance at the subsystems shows us the main suspect - System.Data.SqlClient or, in other words, the time required to get data from the SQL server.
- To better distinguish time required for communication with the database, let’s create a separate Database communication subsystem.
There is a faster way of doing this comparing with the one described in the previous step. To quickly create a new subsystem for a certain namespace, right click the corresponding namespace in the subsystems list. In the context menu, select Add rule to new subsystem.
Finally, our subsystem must look like follows.
Note that we also added a rule for the System.Transactions namespace. .NET uses it for supporting transactions initiated in SQL Server, ADO.NET, and so on.
- If we check the btnLoad_Click call now, we’ll get the following result.
It seems that our SQL Server communicates without significant lags (163ms) and doesn’t require any improvements.
- Finally, we can take an overview of how our app utilizes various subsystems.