Skip to content

Conversation

@bitfaster
Copy link
Owner

@bitfaster bitfaster commented Mar 17, 2023

Address #311: provide an overload that allows passing args into the factory method to avoid closure allocs. This PR so far only addresses the basic support for LRU/LFU instance methods.

To support across the board (builder support, ICache etc.) is a breaking change, and requires further changes to Atomic/Scoped etc.

Some variation on GetOrAdd, but seems to be noise not regression.

Method Runtime Mean Ratio Code Size Allocated
ConcurrentDictionary .NET 6.0 7.156 ns 1.00 1,523 B -
FastConcurrentLru .NET 6.0 10.178 ns 1.42 10,960 B -
ConcurrentLru .NET 6.0 16.180 ns 2.26 12,506 B -
AtomicFastLru .NET 6.0 20.102 ns 2.81 - -
FastConcurrentTLru .NET 6.0 11.774 ns 1.65 11,326 B -
ConcurrentTLru .NET 6.0 17.805 ns 2.49 12,944 B -
ConcurrentLfu .NET 6.0 31.290 ns 4.20 - -
ClassicLru .NET 6.0 48.525 ns 6.78 - -
RuntimeMemoryCacheGet .NET 6.0 112.797 ns 15.78 49 B 32 B
ExtensionsMemoryCacheGet .NET 6.0 61.136 ns 9.17 78 B 24 B
ConcurrentDictionary .NET Framework 4.8 14.167 ns 1.00 4,127 B -
FastConcurrentLru .NET Framework 4.8 15.177 ns 1.07 23,788 B -
ConcurrentLru .NET Framework 4.8 18.888 ns 1.33 24,084 B -
AtomicFastLru .NET Framework 4.8 30.609 ns 2.16 358 B -
FastConcurrentTLru .NET Framework 4.8 45.442 ns 3.21 24,052 B -
ConcurrentTLru .NET Framework 4.8 48.891 ns 3.45 24,416 B -
ConcurrentLfu .NET Framework 4.8 54.348 ns 3.84 - -
ClassicLru .NET Framework 4.8 59.530 ns 4.20 - -
RuntimeMemoryCacheGet .NET Framework 4.8 277.100 ns 19.57 33 B 32 B
ExtensionsMemoryCacheGet .NET Framework 4.8 115.311 ns 8.14 82 B 24 B

@bitfaster bitfaster changed the title arg factory has arg to avoid closure allocs Mar 17, 2023
@bitfaster bitfaster changed the title factory has arg to avoid closure allocs factory delegate has arg to avoid closure allocs Mar 17, 2023
@coveralls
Copy link

coveralls commented Mar 17, 2023

Coverage Status

Coverage: 96.381%. Remained the same when pulling 3d2ebdb on users/alexpeck/arg into 4320996 on main.

@bitfaster bitfaster marked this pull request as ready for review April 25, 2023 02:45
@bitfaster
Copy link
Owner Author

bitfaster commented Apr 25, 2023

Re-ran benchmarks, after refactoring item creation inside TryAdd, this actually results in a repeatable speed up for GetOrAdd test cases.

Method Runtime Mean StdDev Ratio Code Size
ConcurrentDictionary .NET 6.0 7.452 ns 0.0456 ns 1.00 1,523 B
FastConcurrentLru .NET 6.0 8.823 ns 0.0349 ns 1.18 7,220 B
ConcurrentLru .NET 6.0 15.043 ns 0.1376 ns 2.02 7,467 B
AtomicFastLru .NET 6.0 20.904 ns 0.0803 ns 2.81 -
FastConcurrentTLru .NET 6.0 11.211 ns 0.1258 ns 1.50 7,629 B
ConcurrentTLru .NET 6.0 16.311 ns 0.0838 ns 2.19 7,893 B
ConcurrentLfu .NET 6.0 29.951 ns 2.4897 ns 4.00 -
ClassicLru .NET 6.0 48.459 ns 0.1990 ns 6.50 -
RuntimeMemoryCacheGet .NET 6.0 113.184 ns 0.5517 ns 15.19 49 B
ExtensionsMemoryCacheGet .NET 6.0 61.594 ns 0.7521 ns 8.27 78 B
ConcurrentDictionary .NET Framework 4.8 13.524 ns 0.0775 ns 1.00 4,127 B
FastConcurrentLru .NET Framework 4.8 14.058 ns 0.1021 ns 1.04 23,808 B
ConcurrentLru .NET Framework 4.8 19.400 ns 0.0721 ns 1.43 24,112 B
AtomicFastLru .NET Framework 4.8 29.079 ns 0.1903 ns 2.15 358 B
FastConcurrentTLru .NET Framework 4.8 44.272 ns 0.3113 ns 3.27 24,080 B
ConcurrentTLru .NET Framework 4.8 48.344 ns 0.1379 ns 3.58 24,432 B
ConcurrentLfu .NET Framework 4.8 54.511 ns 0.7723 ns 4.03 -
ClassicLru .NET Framework 4.8 59.196 ns 0.2562 ns 4.38 -
RuntimeMemoryCacheGet .NET Framework 4.8 279.615 ns 1.2198 ns 20.68 33 B
ExtensionsMemoryCacheGet .NET Framework 4.8 116.184 ns 0.4734 ns 8.59 82 B

For both cycle and zipf any change is noise.

cycle-arg

Method Runtime Mean StdDev Ratio Allocated
FastConcurrentLru .NET 6.0 23.37 us 0.098 us 1.00 8.51 KB
ConcurrentLru .NET 6.0 24.74 us 0.107 us 1.06 8.51 KB
ConcurrentLruEvent .NET 6.0 25.59 us 0.158 us 1.10 12.29 KB
FastConcurrentTLru .NET 6.0 23.89 us 0.098 us 1.02 9.45 KB
ConcurrentTLru .NET 6.0 25.50 us 0.182 us 1.09 9.45 KB
ClassicLru .NET 6.0 17.23 us 0.288 us 0.73 14 KB
FastConcurrentLru .NET Framework 4.8 37.02 us 0.439 us 1.00 14.34 KB
ConcurrentLru .NET Framework 4.8 38.51 us 0.177 us 1.04 14.34 KB
ConcurrentLruEvent .NET Framework 4.8 39.56 us 0.261 us 1.07 18.13 KB
FastConcurrentTLru .NET Framework 4.8 48.16 us 0.107 us 1.30 15.29 KB
ConcurrentTLru .NET Framework 4.8 50.57 us 0.211 us 1.37 15.29 KB
ClassicLru .NET Framework 4.8 21.95 us 0.087 us 0.59 17.05 KB

cycle-main

Method Runtime Mean StdDev Ratio Allocated
FastConcurrentLru .NET 6.0 22.99 us 0.159 us 1.00 8.51 KB
ConcurrentLru .NET 6.0 24.63 us 0.098 us 1.07 8.51 KB
ConcurrentLruEvent .NET 6.0 25.78 us 0.113 us 1.12 12.29 KB
FastConcurrentTLru .NET 6.0 23.95 us 0.187 us 1.04 9.45 KB
ConcurrentTLru .NET 6.0 25.22 us 0.158 us 1.10 9.45 KB
ClassicLru .NET 6.0 17.00 us 0.091 us 0.74 14 KB
FastConcurrentLru .NET Framework 4.8 36.41 us 0.415 us 1.00 14.34 KB
ConcurrentLru .NET Framework 4.8 38.15 us 0.203 us 1.05 14.34 KB
ConcurrentLruEvent .NET Framework 4.8 39.23 us 0.100 us 1.08 18.13 KB
FastConcurrentTLru .NET Framework 4.8 48.30 us 0.267 us 1.33 15.29 KB
ConcurrentTLru .NET Framework 4.8 50.48 us 0.501 us 1.39 15.29 KB
ClassicLru .NET Framework 4.8 22.06 us 0.201 us 0.61 17.05 KB

zipf-arg

Method Runtime Mean StdDev Ratio Allocated
ClassicLru .NET 6.0 109.9 ns 0.46 ns 1.00 64 B
FastConcurrentLru .NET 6.0 106.2 ns 0.39 ns 0.97 34 B
ConcurrentLru .NET 6.0 113.8 ns 0.41 ns 1.04 34 B
FastConcurrentTLru .NET 6.0 114.0 ns 0.39 ns 1.04 40 B
ConcurrentTLru .NET 6.0 126.1 ns 0.74 ns 1.15 41 B

zipf-main

Method Runtime Mean StdDev Ratio Allocated
ClassicLru .NET 6.0 110.8 ns 0.52 ns 1.00 66 B
FastConcurrentLru .NET 6.0 102.2 ns 0.41 ns 0.92 34 B
ConcurrentLru .NET 6.0 114.5 ns 0.35 ns 1.03 33 B
FastConcurrentTLru .NET 6.0 114.7 ns 0.62 ns 1.03 40 B
ConcurrentTLru .NET 6.0 116.6 ns 0.43 ns 1.05 38 B

@bitfaster bitfaster merged commit 8465588 into main Apr 25, 2023
@bitfaster bitfaster deleted the users/alexpeck/arg branch April 25, 2023 02:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature request] Allow to pass additional factory argument to the GetOrAdd/GetOrAddAsync cache methods

3 participants