@@ -172,11 +172,11 @@ Cache size = *N* / 10 (so we can cache 10% of the total set). ConcurrentLru has
172172
173173| Method | Mean | Error | StdDev | Ratio | RatioSD |
174174| ------------------- | ---------:| --------:| --------:| ------:| --------:|
175- | ClassicLru | 157.3 ns | 1.67 ns | 1.48 ns | 1.00 | 0.00 |
176- | FastConcurrentLru | 165.4 ns | 1.17 ns | 1.04 ns | 1.05 | 0.01 |
177- | ConcurrentLru | 176 .1 ns | 1.22 ns | 1.08 ns | 1.12 | 0.01 |
178- | FastConcurrentTLru | 247.9 ns | 3.58 ns | 2.80 ns | 1.58 | 0.02 |
179- | ConcurrentTLru | 259.0 ns | 3.61 ns | 3.20 ns | 1.65 | 0.03 |
175+ | ClassicLru | 175.7 ns | 2.75 ns | 2.43 ns | 1.00 | 0.00 |
176+ | FastConcurrentLru | 180.2 ns | 2.55 ns | 2.26 ns | 1.03 | 0.02 |
177+ | ConcurrentLru | 189 .1 ns | 3.14 ns | 2.94 ns | 1.08 | 0.03 |
178+ | FastConcurrentTLru | 261.4 ns | 4.53 ns | 4.01 ns | 1.49 | 0.04 |
179+ | ConcurrentTLru | 266.1 ns | 3.96 ns | 3.51 ns | 1.51 | 0.03 |
180180
181181### Raw Lookup speed
182182
@@ -188,16 +188,16 @@ In this test the same items are fetched repeatedly, no items are evicted. Repres
188188
189189FastConcurrentLru does not allocate and is approximately 10x faster than System.Runtime.Caching.MemoryCache or the newer Microsoft.Extensions.Caching.Memory.MemoryCache.
190190
191- | Method | Mean | Error | StdDev | Ratio | Gen 0 | Allocated |
192- | ---------------------- | ----------:| ---------:| ---------:| ------:| -------:| ----------:|
193- | ConcurrentDictionary | 16.88 ns | 0.276 ns | 0.245 ns | 1.00 | - | - |
194- | FastConcurrentLru | 23.27 ns | 0.491 ns | 0.565 ns | 1.38 | - | - |
195- | ConcurrentLru | 26.77 ns | 0.512 ns | 0.666 ns | 1.60 | - | - |
196- | FastConcurrentTLru | 54.35 ns | 0.650 ns | 0.576 ns | 3.22 | - | - |
197- | ConcurrentTLru | 60.10 ns | 1.024 ns | 1.501 ns | 3.53 | - | - |
198- | ClassicLru | 68.04 ns | 1.400 ns | 2.221 ns | 4.12 | - | - |
199- | RuntimeMemoryCache | 280.16 ns | 5.607 ns | 7.486 ns | 16.59 | 0.0153 | 32 B |
200- | ExtensionsMemoryCache | 342.72 ns | 3.729 ns | 3.114 ns | 20.29 | 0.0114 | 24 B |
191+ | Method | Mean | Error | StdDev | Ratio | Gen 0 | Allocated |
192+ | ------------------------- | ----------:| ---------:| ---------:| ------:| -------:| ----------:|
193+ | ConcurrentDictionary | 16.76 ns | 0.322 ns | 0.285 ns | 1.00 | - | - |
194+ | FastConcurrentLru | 18.94 ns | 0.249 ns | 0.220 ns | 1.13 | - | - |
195+ | ConcurrentLru | 21.46 ns | 0.204 ns | 0.191 ns | 1.28 | - | - |
196+ | FastConcurrentTLru | 41.57 ns | 0.450 ns | 0.376 ns | 2.48 | - | - |
197+ | ConcurrentTLru | 43.95 ns | 0.588 ns | 0.521 ns | 2.62 | - | - |
198+ | ClassicLru | 67.62 ns | 0.901 ns | 0.799 ns | 4.03 | - | - |
199+ | RuntimeMemoryCacheGet | 279.70 ns | 3.825 ns | 3.578 ns | 16.70 | 0.0153 | 32 B |
200+ | ExtensionsMemoryCacheGet | 341.67 ns | 6.617 ns | 6.499 ns | 20.35 | 0.0114 | 24 B |
201201
202202
203203## ConcurrentLru Throughput
@@ -222,23 +222,32 @@ public bool TryGet(K key, out V value)
222222 I item ;
223223 if (dictionary .TryGetValue (key , out item ))
224224 {
225- if (this .policy .ShouldDiscard (item )) // 1
226- {
227- this .Move (item , ItemDestination .Remove );
228- value = default (V );
229- return false ;
230- }
231-
232- value = item .Value ;
233- this .policy .Touch (item );
234- this .hitCounter .IncrementHit (); // 2
235- return true ;
225+ return GetOrDiscard (item , out value );
236226 }
237227
238228 value = default (V );
239- this .hitCounter .IncrementMiss (); // 2
229+ this .hitCounter .IncrementMiss ();
240230 return false ;
241231}
232+
233+ // AggressiveInlining forces the JIT to inline policy.ShouldDiscard(). For LRU policy
234+ // the first branch is completely eliminated due to JIT time constant propogation.
235+ [MethodImpl (MethodImplOptions .AggressiveInlining )]
236+ private bool GetOrDiscard (I item , out V value )
237+ {
238+ if (this .policy .ShouldDiscard (item )) // 1
239+ {
240+ this .Move (item , ItemDestination .Remove );
241+ this .hitCounter .IncrementMiss (); // 2
242+ value = default (V );
243+ return false ;
244+ }
245+
246+ value = item .Value ;
247+ this .policy .Touch (item ); // 1
248+ this .hitCounter .IncrementHit (); // 2
249+ return true ;
250+ }
242251```
243252
244253### FastConcurrentLru (LruPolicy & NullHitCounter)
0 commit comments