TAChart: mark drawing can be up to 40% faster
Original Reporter info from Mantis: Marcin Wiazowski
-
Reporter name:
Original Reporter info from Mantis: Marcin Wiazowski
- Reporter name:
Description:
Mark drawing can be made faster by making some optimizations; the most noticeable speedup is for multi-value data sources.
In procedure TBasicPointSeries.DrawLabels():
- a call to GetLabelDirection() is made in every loop iteration - although it may be done when really needed, i.e. just before the DrawLabel() call
- a "Styles" handling is made in every iteration of the inner loop - although it may be done when really needed, i.e. just before the DrawLabel() call
- there is:
y := NumberOr(Source[i]^.YList[si-1], 0);
if IsNaN(y) then Continue;
the second line can be removed, since NumberOr() guarantees, that "y" is never NaN
- there is:
if IsNan(Source[i]^.Point) then
continue;
y := Source[i]^.Y; <==== y is never NaN
ysum := y; <==== ysum is never NaN
...
y := NumberOr(Source[i]^.YList[si-1], 0); <==== y is never NaN
...
if IsNaN(ysum) then ysum := y else ysum += y; <==== see below
"ysum" cannot become NaN when initialized, and later it can be only incremented by "y", which is also guaranteed not to be NaN, so - in fact - it can never become NaN. So calling "IsNaN(ysum)" always returns False. So "if IsNaN(ysum) then ysum := y else ysum += y;" can be changed just to "ysum += y;"
And the most important optimization: the TBasicPointSeries.GetLabelDirection() method uses a TBasicPointSeries.Extent() function - which makes a call to data source's ExtentCumulative() or ExtentList() method. They are very fast for NON multi-value sources (since extent is cached), and horribly slow for multi-value sources. Unfortunately, TBasicPointSeries.GetLabelDirection() is called in loops, so - for multi-value sources - this makes a large slowdown.
Solution: Since GetLabelDirection() is strict private, an additional parameter can be added to pass an extent - that has been earlier saved to variable, before the loop.
The attached test program is artificial - it uses stacked, multi-valued line series, but only marks are visible - no pointers or lines. But this is just to test the hardest code path at once, and not to be influenced by line or pointer drawing times. What's more, on a multitasking operating system, measuring time difference like 10 ms is not very reliable - but a difference of 1000 ms can be trusted in; to force longer testing times, a lot of data points are drawn on the chart.
Times measured on a low-end laptop: without patch about 3370 ms, with patch about 1860 ms.
Regards