akamsteeg / AtleX.HaveIBeenPwned

A fully async .NET Standard client library for the API of HaveIBeenPwned.com
https://www.nuget.org/packages/AtleX.HaveIBeenPwned/
MIT License
5 stars 0 forks source link

Investigate using pooled arrays as buffers for K-Anonimity #98

Closed akamsteeg closed 3 months ago

akamsteeg commented 3 months ago

Currently, a new byte array is created for every password check. This increases pressure on the GC and can lead to heap fragmentation if we do this a lot. .NET Core has an ArrayPool<T> ever since version 1.0. We should investigate if we can use ArrayPool<byte> in the KAnonimityHelper to reduce allocations.

akamsteeg commented 3 months ago

This is looking good. If we compare numbers over all three frameworks for all benchmarks we perform about the same. (Different runs will always slightly differ in results, my dev machine runs more than the benchmark process.). However, allocations are lower and most likely this will add up significantly when a longer running application is using this library. Overall, good gain.

Old:

Method Toolchain password Mean Ratio Allocated Alloc Ratio
GetKAnonimityPartsForPassword .NET 6.0 -&Hx 238.6 ns 0.99 312 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&Hx 241.2 ns 1.00 312 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&Hx 3,011.4 ns 12.46 4710 B 15.10
GetKAnonimityPartsForPassword .NET 6.0 -&HxcB_d 237.4 ns 1.00 312 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&HxcB_d 235.8 ns 1.00 312 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&HxcB_d 2,975.1 ns 12.60 4710 B 15.10
GetKAnonimityPartsForPassword .NET 6.0 -&HxcB_dH+M@BZAX 239.8 ns 1.03 320 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&HxcB_dH+M@BZAX 232.3 ns 1.00 320 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&HxcB_dH+M@BZAX 2,988.6 ns 12.86 4718 B 14.74
GetKAnonimityPartsForPassword .NET 6.0 -&Hxc(...)&,#x} [32] 244.2 ns 1.02 336 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&Hxc(...)&,#x} [32] 239.3 ns 1.00 336 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&Hxc(...)&,#x} [32] 3,043.0 ns 12.75 4734 B 14.09
GetKAnonimityPartsForPassword .NET 6.0 -&Hxc(...)QbuAz [64] 324.9 ns 1.03 368 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&Hxc(...)QbuAz [64] 317.0 ns 1.00 368 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&Hxc(...)QbuAz [64] 3,102.2 ns 9.79 4766 B 12.95

New:

Method Toolchain password Mean Ratio Allocated Alloc Ratio
GetKAnonimityPartsForPassword .NET 6.0 -&Hx 248.2 ns 1.02 280 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&Hx 242.6 ns 1.00 280 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&Hx 2,928.4 ns 12.08 4710 B 16.82
GetKAnonimityPartsForPassword .NET 6.0 -&HxcB_d 245.0 ns 1.01 280 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&HxcB_d 242.4 ns 1.00 280 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&HxcB_d 2,927.3 ns 12.08 4710 B 16.82
GetKAnonimityPartsForPassword .NET 6.0 -&HxcB_dH+M@BZAX 248.9 ns 1.06 280 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&HxcB_dH+M@BZAX 236.0 ns 1.00 280 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&HxcB_dH+M@BZAX 2,927.2 ns 12.41 4718 B 16.85
GetKAnonimityPartsForPassword .NET 6.0 -&Hxc(...)&,#x} [32] 246.1 ns 1.02 280 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&Hxc(...)&,#x} [32] 250.2 ns 1.00 280 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&Hxc(...)&,#x} [32] 2,934.2 ns 12.06 4734 B 16.91
GetKAnonimityPartsForPassword .NET 6.0 -&Hxc(...)QbuAz [64] 331.8 ns 1.07 280 B 1.00
GetKAnonimityPartsForPassword .NET 8.0 -&Hxc(...)QbuAz [64] 309.9 ns 1.00 280 B 1.00
GetKAnonimityPartsForPassword .NET Framework 4.8.1 -&Hxc(...)QbuAz [64] 3,043.1 ns 9.81 4766 B 17.02