Closed pyscripter closed 4 years ago
I'll take care of the defines, The headers are "old". Thank you.
Oh boy, "massively" is a nice understatement.
Here are the results "benchmark" (64-bit) on "seaborn" with one repetition on my work PC:
Repeat 1 times
Factory | Load | Draw | Total
Pascal | 47375 | 39687 | 87062
Direct 2D | 938 | 1141 | 2079
Cairo | 281 | 109 | 390
In drawing in particular Cairo is 11x faster than D2D and 400x faster than Pascal!
I wonder what is the reason for that. Why don't we see similar results with smaller svgs...
If you drop this SVG on Firefox it is also drawn a lot faster than D2D and Pascal, but not as fast as Cairo (not timed, just "feeling")
One encouraging thing is that at least all three factories produce the same visual output.
Pull request merged.
I can't wait to try Cairo with lots of "little icons" using SVGExplorer to measure performance again ;-)
@luebbe Could you please check https://github.com/preshing/cairo-windows This guy produces releases packaging all cairo functionality in a single dll:
This repository is meant to help create Cairo DLLs for Windows. Both 32-bit and 64-bit versions can be built. The resulting cairo.dll file is fully self-contained and does not depend on any other third-party DLLs. FreeType support is included.
The releases include DLLs compiled last month. It would a huge help to have to deploy one dll as opposed to 15.
Update: Actually it might not help much because it does not include librsvg, which is the one with many dependencies.
With the changes in SVG.pas (see attached)
Repeat 1 times
Factory | Load | Draw | Gray | Draw | Fixed | Draw | Total |
Pascal | 312 | 2141 | 313 | 2140 | 625 | 2078 | 7609 |
Direct 2D | 719 | 859 | 688 | 906 | 735 | 921 | 4828 |
Cairo | 204 | 203 | 109 | 188 | 109 | 187 | 1000 |
However the painting comparison is not fair for SVG.pas. It draws directly on the SVGIconImage Canvas whilst the other two do buffered painting. A fairer comparison would be to draw to a Bitmap. In a production setting you would set DoubleBuffered on on the SVGIconImage and when it is painted with SVG the painting would be on a bitmap.
@carloBarazzetta Could you please commit the changes @luebbe Could you please change the BenchmarkDraw to paint to a bitmap?
You want believe this. With the above changes TSVG painting is super fast. Faster than Direct2D and comparable to Cairo. To try:
I 'd love to see the updated benchmarks on Bitmap.
Update TSVG draws this SVG faster than Cairo
One last thing. There are a number of Warnings when I build UBenchmark (mostly on the Cairo side). Could these warnings be eliminated?
@carloBarazzetta Could you please commit the changes
Done, but changed FIdDict.TryAdd(Name, Result); as: if not FIdDict.ContainsKey(Name) then FIdDict.Add(Name, Result); for backward compatibility with XE6.
One last thing. There are a number of Warnings when I build UBenchmark (mostly on the Cairo side). Could these warnings be eliminated?
These are thrown, because I haven't found time yet to implement the recoloring using xmllite. So the getters don't return a value. I can make them return default values and add a Todo until this is done...
Done, but changed FIdDict.TryAdd(Name, Result);
in TSVG.FindByID
if not FIdDict.ContainsKey(Name) then
`This is not needed, since we checked above with TryGetValue
Is this correct?
function TSVG.FindByID(const Name: string): TSVGObject;
begin
if not FIdDict.TryGetValue(Name, Result) then
begin
Result := inherited FindById(Name);
if Assigned(Result) then
FIdDict.Add(Name, Result);
end;
end;
function TSVG.FindByID(const Name: string): TSVGObject;
begin
if not FIdDict.TryGetValue(Name, Result) then
begin
Result := inherited FindById(Name);
FIdDict.Add(Name, Result);
end;
end;
Even if the Result is nil we still add it, so that we do not search for the same Name again.
@luebbe Could you please change the BenchmarkDraw to paint to a bitmap?
@pyscripter Hi Kiriakos, I made some changes to the benchmark form and functionality, but don't quite understand how to do this? SvgIconImageCollection just has a Draw to Canvas method?!?
@luebbe Could you please change the BenchmarkDraw to paint to a bitmap?
@pyscripter Hi Kiriakos, I made some changes to the benchmark form and functionality, but don't quite understand how to do this? SvgIconImageCollection just has a Draw to Canvas method?!?
Create a bitmap of the right size (same as SVGIconImage) and draw to the Bitmap.Canvas.
There is somewhere the code CreateBitmaps if you want to have a look.
OK, but that means that the painting itself is not visible, if I understand you correctly?
means that the painting itself is not visible, if I understand you correctly?
Yes. We are still comparing painting speed on the same basis for all factories. Otherwise with TSVG you got the screen updating after every SVG element is painted and this is not a fair comparison.
Generally you prevent that by setting DoubleBuffering to True, but this has no effect if you paint on the SVGIconImage.Canvas outside the Paint method.
I made the drawing on TBitmap.Canvas an option in #128. Default is visible. OK this way?
Maybe we should turn all three options off by default, because cairo can't recolor yet and thus gains an undeserved advantage, since it does nothing.
TSVG is the fastest! Paints 3 times as fast as Cairo!
Benchmark: Repeat 10 times. Draw invisible.
Factory | Load | Draw | Total
Pascal | 2312 | 329 | 2656
Direct 2D | 6266 | 7734 | 14000
Cairo | 1860 | 984 | 2844
Also load seaborn.svg and try to resize the form with each of the 3 factories.
@luebbe Nice job with UBenchmark...
Thanks 🥰 ! The compliments go back to @pyscripter for your work on TSVG. This should improve resizing of Imagelists dramatically.
I've pushed now a new version of Benchmark project, compatible also with XE6.
Just saw it. Any reason why you removed the option to draw on an invisible Bitmap?
Yeehaaaw!
Using the "Butterfly":
Benchmark: Repeat 50 times. Draw visible.
Factory | Load | Draw | Total
Pascal | 250 | 250 | 500
Direct 2D | 359 | 391 | 765
Cairo | 110 | 297 | 407
Benchmark: Repeat 50 times. Draw invisible.
Factory | Load | Draw | Total
Pascal | 250 | 16 | 266
Direct 2D | 265 | 360 | 625
Cairo | 125 | 62 | 187
We should update our Benchmark in the Readme 😎
I repeated the "invisible" draw several times. Pascal and Cairo times are pretty much consistent, but D2D can sometimes be unlucky.
Benchmark: Repeat 50 times. Draw invisible.
Factory | Load | Draw | Total
Pascal | 250 | 16 | 266
Direct 2D | 265 | 360 | 625
Cairo | 125 | 62 | 187
Benchmark: Repeat 50 times. Draw invisible.
Factory | Load | Draw | Total
Pascal | 235 | 15 | 250
Direct 2D | 110 | 140 | 250
Cairo | 94 | 62 | 156
Benchmark: Repeat 50 times. Draw invisible.
Factory | Load | Draw | Total
Pascal | 235 | 15 | 250
Direct 2D | 125 | 219 | 344
Cairo | 109 | 63 | 172
Benchmark: Repeat 50 times. Draw invisible.
Factory | Load | Draw | Total
Pascal | 235 | 15 | 250
Direct 2D | 125 | 94 | 219
Cairo | 125 | 62 | 187
Benchmark: Repeat 50 times. Draw invisible.
Factory | Load | Draw | Total
Pascal | 235 | 15 | 250
Direct 2D | 125 | 125 | 266
Cairo | 125 | 47 | 187
Benchmark: Repeat 50 times. Draw invisible.
Factory | Load | Draw | Total
Pascal | 234 | 16 | 250
Direct 2D | 125 | 93 | 218
Cairo | 125 | 47 | 172
Benchmark: Repeat 50 times. Draw invisible.
Factory | Load | Draw | Total
Pascal | 235 | 15 | 250
Direct 2D | 109 | 94 | 203
Cairo | 110 | 62 | 172
One thing is sure. TSVG vastly outperfomrs the others in Drawing speed. And you typically load once but paint many times. There are still many areas of potential improvement it TSVG.
One thing to try is the UseGPU flag for D2D. In my computers it makes things worse or has not impact. But I do not have fast GPUs installed. Does it have any impact in your hardware?
Please replace all conditional defines from {$IFDEF WIN32} to {$IFDEF MSWINDOWS}
By the way try the factories on this one. Cairo is massively faster seaborn.zip