SVG
SVG copied to clipboard
Memory usage optimization for SvgElement
Reference Issue
What does this implement/fix? Explain your changes.
Defers memory allocation until needed when creating new SvgElement
's from 712
bytes to 200
bytes.
Any other comments?
dotnet run -c Release -f netcoreapp3.1 -- -f '*SvgDocument_*'
- master branch
| Method | Mean | Error | StdDev | Op/s | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
|----------------------------------- |----------:|----------:|----------:|-------:|-----:|----------:|---------:|---------:|----------:|
| SvgDocument_Open_AJ_Digital_Camera | 5.214 ms | 0.0724 ms | 0.0605 ms | 191.77 | 2 | 492.1875 | 203.1250 | - | 2.79 MB |
| SvgDocument_Open_Issue_134_01 | 29.884 ms | 0.5288 ms | 0.4687 ms | 33.46 | 3 | 2031.2500 | 812.5000 | 406.2500 | 11.72 MB |
| SvgDocument_Open_Tiger | 4.766 ms | 0.0774 ms | 0.0647 ms | 209.83 | 1 | 398.4375 | 195.3125 | - | 2.23 MB |
- SvgElementMemoryUsageOptimization branch
| Method | Mean | Error | StdDev | Op/s | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
|----------------------------------- |----------:|----------:|----------:|-------:|-----:|----------:|---------:|---------:|----------:|
| SvgDocument_Open_AJ_Digital_Camera | 4.831 ms | 0.0554 ms | 0.0491 ms | 206.99 | 2 | 445.3125 | 218.7500 | - | 2.46 MB |
| SvgDocument_Open_Issue_134_01 | 27.144 ms | 0.5050 ms | 0.5816 ms | 36.84 | 3 | 1812.5000 | 656.2500 | 218.7500 | 10.66 MB |
| SvgDocument_Open_Tiger | 4.397 ms | 0.0491 ms | 0.0410 ms | 227.42 | 1 | 367.1875 | 132.8125 | - | 1.91 MB |
- master
| Method | Mean | Error | StdDev | Op/s | Ratio | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------------- |-----------:|----------:|----------:|--------------:|------:|-----:|-------:|------:|------:|----------:|
| SvgElement_new_EmptyClass | 1.897 ns | 0.0141 ns | 0.0125 ns | 527,034,350.4 | 0.008 | 1 | - | - | - | - |
| SvgElement_new_SvgElementEmpty | 239.817 ns | 2.9742 ns | 2.7821 ns | 4,169,837.8 | 1.000 | 2 | 0.1702 | - | - | 712 B |
- defer initialization of
_nodes
| Method | Mean | Error | StdDev | Op/s | Ratio | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------------- |-----------:|----------:|----------:|--------------:|------:|-----:|-------:|------:|------:|----------:|
| SvgElement_new_EmptyClass | 1.904 ns | 0.0210 ns | 0.0186 ns | 525,156,053.4 | 0.008 | 1 | - | - | - | - |
| SvgElement_new_SvgElementEmpty | 227.216 ns | 3.2265 ns | 2.6943 ns | 4,401,091.9 | 1.000 | 2 | 0.1624 | - | - | 680 B |
- defer initialization of
_eventHandlers
| Method | Mean | Error | StdDev | Op/s | Ratio | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------------- |-----------:|----------:|----------:|--------------:|------:|-----:|-------:|------:|------:|----------:|
| SvgElement_new_EmptyClass | 1.905 ns | 0.0279 ns | 0.0233 ns | 524,995,126.5 | 0.008 | 1 | - | - | - | - |
| SvgElement_new_SvgElementEmpty | 232.512 ns | 4.4016 ns | 6.8527 ns | 4,300,859.1 | 1.000 | 2 | 0.1547 | - | - | 648 B |
- defer initialization of
_children
| Method | Mean | Error | StdDev | Op/s | Ratio | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------------- |-----------:|----------:|----------:|--------------:|------:|-----:|-------:|------:|------:|----------:|
| SvgElement_new_EmptyClass | 1.406 ns | 0.0114 ns | 0.0101 ns | 711,160,475.5 | 0.007 | 1 | - | - | - | - |
| SvgElement_new_SvgElementEmpty | 213.413 ns | 1.9136 ns | 1.5979 ns | 4,685,749.5 | 1.000 | 2 | 0.1376 | - | - | 576 B |
- defer initialization of
_styles
| Method | Mean | Error | StdDev | Op/s | Ratio | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------------- |-----------:|----------:|----------:|--------------:|------:|-----:|-------:|------:|------:|----------:|
| SvgElement_new_EmptyClass | 1.886 ns | 0.0244 ns | 0.0216 ns | 530,298,131.8 | 0.01 | 1 | - | - | - | - |
| SvgElement_new_SvgElementEmpty | 160.923 ns | 2.1405 ns | 1.7874 ns | 6,214,149.2 | 1.00 | 2 | 0.1204 | - | - | 504 B |
- defer initialization of
_customAttributes
| Method | Mean | Error | StdDev | Op/s | Ratio | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------------- |----------:|----------:|----------:|--------------:|------:|-----:|-------:|------:|------:|----------:|
| SvgElement_new_EmptyClass | 1.903 ns | 0.0368 ns | 0.0362 ns | 525,505,200.1 | 0.14 | 1 | - | - | - | - |
| SvgElement_new_SvgElementEmpty | 13.735 ns | 0.2923 ns | 0.4636 ns | 72,804,361.3 | 1.00 | 2 | 0.0478 | - | - | 200 B |
https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmltextreader?view=net-5.0#remarks
Starting with the .NET Framework 2.0, we recommend that you create XmlReader instances by using the XmlReader.Create method to take advantage of new functionality.
| Method | Mean | Error | StdDev | Op/s | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------------ |---------:|---------:|---------:|------------:|-----:|-------:|------:|------:|----------:|
| SvgDocument_new_XmlTextReader | 777.1 ns | 15.45 ns | 35.82 ns | 1,286,812.8 | 1 | 2.4090 | - | - | 9.84 KB |
Empty XmlTextReader allocates 10KB !
I think this can now be merged because. The Roslyn Compiler can soon do switches on ReadonlySpans see issue. https://github.com/dotnet/csharplang/issues/1881