codebude / QRCoder

A pure C# Open Source QR Code implementation
MIT License
4.59k stars 1.09k forks source link

BitmapByteQRCode performance optimization #566

Closed codebude closed 3 months ago

codebude commented 3 months ago

Summary

I tried to optimize the performance of BitmapByteQRCode by removing loops and pre-calculating data where possible. Also fixed object size/capacity to keep memory footprint low.

Performance details

Before this PR Method Mean Error StdDev Gen0 Gen1 Gen2 Allocated
RenderBitmapByteQRCodeSmall 2.369 ms 0.0457 ms 0.0489 ms 496.0938 210.9375 210.9375 7.22 MB
RenderBitmapByteQRCodeMedium 7.903 ms 0.1557 ms 0.1456 ms 1734.3750 750.0000 750.0000 21.26 MB
RenderBitmapByteQRCodeBig 89.976 ms 1.0133 ms 0.8983 ms 18000.0000 2166.6667 2166.6667 265.99 MB
RenderBitmapByteQRCodeHuge 2,090.730 ms 33.4541 ms 31.2930 ms 407000.0000 8000.0000 8000.0000 6775.64 MB
After/with changes from this PR Method Mean Error StdDev Gen0 Gen1 Gen2 Allocated
RenderBitmapByteQRCodeSmall 115.1 us 2.29 us 4.83 us 153.8086 153.8086 153.8086 495.75 KB
RenderBitmapByteQRCodeMedium 163.1 us 3.16 us 4.11 us 299.0723 298.8281 298.8281 1412.45 KB
RenderBitmapByteQRCodeBig 3,156.9 us 62.66 us 87.84 us 988.2813 988.2813 988.2813 18372.12 KB
RenderBitmapByteQRCodeHuge 74,284.9 us 1,432.76 us 1,961.18 us 1000.0000 1000.0000 1000.0000 458983.6 KB
After implementing changes suggested by @Shane32 via PR review Method Mean Error StdDev Gen0 Gen1 Gen2 Allocated
RenderBitmapByteQRCodeSmall 73.79 us 0.901 us 0.799 us 76.9043 76.9043 76.9043 247.3 KB
RenderBitmapByteQRCodeMedium 208.30 us 3.268 us 2.897 us 199.9512 199.9512 199.9512 704.85 KB
RenderBitmapByteQRCodeBig 1,162.20 us 22.314 us 25.697 us 500.0000 500.0000 500.0000 9182.63 KB
RenderBitmapByteQRCodeHuge 57,819.92 us 1,858.610 us 5,450.982 us 833.3333 833.3333 833.3333 229479.24 KB

Test plan

To ensure that the optimizations work out and break anything I added test cases and benchmarks to the project.

codebude commented 3 months ago

@Shane32 May I ask you for a review? (Please be critical with the benchmark project. I tried to exclude the QRCode data generation, as it is ramp-up stuff, from the benchmarks, but I'm not sure, if I did it right.)

codebude commented 3 months ago

Looks great! Benchmarks look great! I've just jotted down some notes for additional improvements that could be made, whether that be within this PR or another one.

Hi Shane, thanks for your review. I implemented and tested all of your suggestions. Thanks for the great input! :-) The results have improved once again. (I have inserted the new benchmarks in the first post above).