@@ -17,12 +17,10 @@ public class LruCycle
1717 private static readonly ConcurrentDictionary < int , int > dictionary = new ConcurrentDictionary < int , int > ( 8 , 9 , EqualityComparer < int > . Default ) ;
1818
1919 private static readonly ClassicLru < int , int > classicLru = new ClassicLru < int , int > ( 8 , 9 , EqualityComparer < int > . Default ) ;
20-
21- private static readonly ConcurrentLru < int , int > concurrentLru
22- = new ConcurrentLru < int , int > ( 8 , 9 , EqualityComparer < int > . Default ) ;
23-
24- private static readonly ConcurrentTLru < int , int > concurrentTLru
25- = new ConcurrentTLru < int , int > ( 8 , 9 , EqualityComparer < int > . Default , TimeSpan . FromMinutes ( 1 ) ) ;
20+ private static readonly ConcurrentLru < int , int > concurrentLru = new ConcurrentLru < int , int > ( 8 , 9 , EqualityComparer < int > . Default ) ;
21+ private static readonly ConcurrentTLru < int , int > concurrentTLru = new ConcurrentTLru < int , int > ( 8 , 9 , EqualityComparer < int > . Default , TimeSpan . FromMinutes ( 1 ) ) ;
22+ private static readonly FastConcurrentLru < int , int > fastConcurrentLru = new FastConcurrentLru < int , int > ( 8 , 9 , EqualityComparer < int > . Default ) ;
23+ private static readonly FastConcurrentTLru < int , int > fastConcurrentTLru = new FastConcurrentTLru < int , int > ( 8 , 9 , EqualityComparer < int > . Default , TimeSpan . FromMinutes ( 1 ) ) ;
2624
2725 private static MemoryCache memoryCache = MemoryCache . Default ;
2826
@@ -95,70 +93,38 @@ public void ConcurrentDictionaryGetOrAdd()
9593 }
9694
9795 [ Benchmark ( OperationsPerInvoke = 24 ) ]
98- public void MemoryCacheGetStringKey ( )
99- {
100- memoryCache . Get ( "1" ) ;
101- memoryCache . Get ( "2" ) ;
102- memoryCache . Get ( "3" ) ;
103- memoryCache . Get ( "4" ) ;
104- memoryCache . Get ( "5" ) ;
105- memoryCache . Get ( "6" ) ;
106-
107- memoryCache . Get ( "1" ) ;
108- memoryCache . Get ( "2" ) ;
109- memoryCache . Get ( "3" ) ;
110- memoryCache . Get ( "4" ) ;
111- memoryCache . Get ( "5" ) ;
112- memoryCache . Get ( "6" ) ;
113-
114- memoryCache . Get ( "1" ) ;
115- memoryCache . Get ( "2" ) ;
116- memoryCache . Get ( "3" ) ;
117- memoryCache . Get ( "4" ) ;
118- memoryCache . Get ( "5" ) ;
119- memoryCache . Get ( "6" ) ;
120-
121- memoryCache . Get ( "1" ) ;
122- memoryCache . Get ( "2" ) ;
123- memoryCache . Get ( "3" ) ;
124- memoryCache . Get ( "4" ) ;
125- memoryCache . Get ( "5" ) ;
126- memoryCache . Get ( "6" ) ;
127- }
128-
129- [ Benchmark ( OperationsPerInvoke = 24 ) ]
130- public void ClassicLruGetOrAdd ( )
96+ public void FastConcurrentLruGetOrAdd ( )
13197 {
13298 // size is 9, so segment size is 3. 6 items will cause queue cycling
13399 // without eviction. Hot => cold when not accessed.
134100 Func < int , int > func = x => x ;
135- classicLru . GetOrAdd ( 1 , func ) ;
136- classicLru . GetOrAdd ( 2 , func ) ;
137- classicLru . GetOrAdd ( 3 , func ) ;
138- classicLru . GetOrAdd ( 4 , func ) ;
139- classicLru . GetOrAdd ( 5 , func ) ;
140- classicLru . GetOrAdd ( 6 , func ) ;
101+ fastConcurrentLru . GetOrAdd ( 1 , func ) ;
102+ fastConcurrentLru . GetOrAdd ( 2 , func ) ;
103+ fastConcurrentLru . GetOrAdd ( 3 , func ) ;
104+ fastConcurrentLru . GetOrAdd ( 4 , func ) ;
105+ fastConcurrentLru . GetOrAdd ( 5 , func ) ;
106+ fastConcurrentLru . GetOrAdd ( 6 , func ) ;
141107
142- classicLru . GetOrAdd ( 1 , func ) ;
143- classicLru . GetOrAdd ( 2 , func ) ;
144- classicLru . GetOrAdd ( 3 , func ) ;
145- classicLru . GetOrAdd ( 4 , func ) ;
146- classicLru . GetOrAdd ( 5 , func ) ;
147- classicLru . GetOrAdd ( 6 , func ) ;
108+ fastConcurrentLru . GetOrAdd ( 1 , func ) ;
109+ fastConcurrentLru . GetOrAdd ( 2 , func ) ;
110+ fastConcurrentLru . GetOrAdd ( 3 , func ) ;
111+ fastConcurrentLru . GetOrAdd ( 4 , func ) ;
112+ fastConcurrentLru . GetOrAdd ( 5 , func ) ;
113+ fastConcurrentLru . GetOrAdd ( 6 , func ) ;
148114
149- classicLru . GetOrAdd ( 1 , func ) ;
150- classicLru . GetOrAdd ( 2 , func ) ;
151- classicLru . GetOrAdd ( 3 , func ) ;
152- classicLru . GetOrAdd ( 4 , func ) ;
153- classicLru . GetOrAdd ( 5 , func ) ;
154- classicLru . GetOrAdd ( 6 , func ) ;
115+ fastConcurrentLru . GetOrAdd ( 1 , func ) ;
116+ fastConcurrentLru . GetOrAdd ( 2 , func ) ;
117+ fastConcurrentLru . GetOrAdd ( 3 , func ) ;
118+ fastConcurrentLru . GetOrAdd ( 4 , func ) ;
119+ fastConcurrentLru . GetOrAdd ( 5 , func ) ;
120+ fastConcurrentLru . GetOrAdd ( 6 , func ) ;
155121
156- classicLru . GetOrAdd ( 1 , func ) ;
157- classicLru . GetOrAdd ( 2 , func ) ;
158- classicLru . GetOrAdd ( 3 , func ) ;
159- classicLru . GetOrAdd ( 4 , func ) ;
160- classicLru . GetOrAdd ( 5 , func ) ;
161- classicLru . GetOrAdd ( 6 , func ) ;
122+ fastConcurrentLru . GetOrAdd ( 1 , func ) ;
123+ fastConcurrentLru . GetOrAdd ( 2 , func ) ;
124+ fastConcurrentLru . GetOrAdd ( 3 , func ) ;
125+ fastConcurrentLru . GetOrAdd ( 4 , func ) ;
126+ fastConcurrentLru . GetOrAdd ( 5 , func ) ;
127+ fastConcurrentLru . GetOrAdd ( 6 , func ) ;
162128 }
163129
164130 [ Benchmark ( OperationsPerInvoke = 24 ) ]
@@ -196,6 +162,41 @@ public void ConcurrentLruGetOrAdd()
196162 concurrentLru . GetOrAdd ( 6 , func ) ;
197163 }
198164
165+ [ Benchmark ( OperationsPerInvoke = 24 ) ]
166+ public void FastConcurrentTLruGetOrAdd ( )
167+ {
168+ // size is 9, so segment size is 3. 6 items will cause queue cycling
169+ // without eviction. Hot => cold when not accessed.
170+ Func < int , int > func = x => x ;
171+ fastConcurrentTLru . GetOrAdd ( 1 , func ) ;
172+ fastConcurrentTLru . GetOrAdd ( 2 , func ) ;
173+ fastConcurrentTLru . GetOrAdd ( 3 , func ) ;
174+ fastConcurrentTLru . GetOrAdd ( 4 , func ) ;
175+ fastConcurrentTLru . GetOrAdd ( 5 , func ) ;
176+ fastConcurrentTLru . GetOrAdd ( 6 , func ) ;
177+
178+ fastConcurrentTLru . GetOrAdd ( 1 , func ) ;
179+ fastConcurrentTLru . GetOrAdd ( 2 , func ) ;
180+ fastConcurrentTLru . GetOrAdd ( 3 , func ) ;
181+ fastConcurrentTLru . GetOrAdd ( 4 , func ) ;
182+ fastConcurrentTLru . GetOrAdd ( 5 , func ) ;
183+ fastConcurrentTLru . GetOrAdd ( 6 , func ) ;
184+
185+ fastConcurrentTLru . GetOrAdd ( 1 , func ) ;
186+ fastConcurrentTLru . GetOrAdd ( 2 , func ) ;
187+ fastConcurrentTLru . GetOrAdd ( 3 , func ) ;
188+ fastConcurrentTLru . GetOrAdd ( 4 , func ) ;
189+ fastConcurrentTLru . GetOrAdd ( 5 , func ) ;
190+ fastConcurrentTLru . GetOrAdd ( 6 , func ) ;
191+
192+ fastConcurrentTLru . GetOrAdd ( 1 , func ) ;
193+ fastConcurrentTLru . GetOrAdd ( 2 , func ) ;
194+ fastConcurrentTLru . GetOrAdd ( 3 , func ) ;
195+ fastConcurrentTLru . GetOrAdd ( 4 , func ) ;
196+ fastConcurrentTLru . GetOrAdd ( 5 , func ) ;
197+ fastConcurrentTLru . GetOrAdd ( 6 , func ) ;
198+ }
199+
199200 [ Benchmark ( OperationsPerInvoke = 24 ) ]
200201 public void ConcurrentTLruGetOrAdd ( )
201202 {
@@ -230,5 +231,72 @@ public void ConcurrentTLruGetOrAdd()
230231 concurrentTLru . GetOrAdd ( 5 , func ) ;
231232 concurrentTLru . GetOrAdd ( 6 , func ) ;
232233 }
234+
235+ [ Benchmark ( OperationsPerInvoke = 24 ) ]
236+ public void ClassicLruGetOrAdd ( )
237+ {
238+ // size is 9, so segment size is 3. 6 items will cause queue cycling
239+ // without eviction. Hot => cold when not accessed.
240+ Func < int , int > func = x => x ;
241+ classicLru . GetOrAdd ( 1 , func ) ;
242+ classicLru . GetOrAdd ( 2 , func ) ;
243+ classicLru . GetOrAdd ( 3 , func ) ;
244+ classicLru . GetOrAdd ( 4 , func ) ;
245+ classicLru . GetOrAdd ( 5 , func ) ;
246+ classicLru . GetOrAdd ( 6 , func ) ;
247+
248+ classicLru . GetOrAdd ( 1 , func ) ;
249+ classicLru . GetOrAdd ( 2 , func ) ;
250+ classicLru . GetOrAdd ( 3 , func ) ;
251+ classicLru . GetOrAdd ( 4 , func ) ;
252+ classicLru . GetOrAdd ( 5 , func ) ;
253+ classicLru . GetOrAdd ( 6 , func ) ;
254+
255+ classicLru . GetOrAdd ( 1 , func ) ;
256+ classicLru . GetOrAdd ( 2 , func ) ;
257+ classicLru . GetOrAdd ( 3 , func ) ;
258+ classicLru . GetOrAdd ( 4 , func ) ;
259+ classicLru . GetOrAdd ( 5 , func ) ;
260+ classicLru . GetOrAdd ( 6 , func ) ;
261+
262+ classicLru . GetOrAdd ( 1 , func ) ;
263+ classicLru . GetOrAdd ( 2 , func ) ;
264+ classicLru . GetOrAdd ( 3 , func ) ;
265+ classicLru . GetOrAdd ( 4 , func ) ;
266+ classicLru . GetOrAdd ( 5 , func ) ;
267+ classicLru . GetOrAdd ( 6 , func ) ;
268+ }
269+
270+ [ Benchmark ( OperationsPerInvoke = 24 ) ]
271+ public void MemoryCacheGetStringKey ( )
272+ {
273+ memoryCache . Get ( "1" ) ;
274+ memoryCache . Get ( "2" ) ;
275+ memoryCache . Get ( "3" ) ;
276+ memoryCache . Get ( "4" ) ;
277+ memoryCache . Get ( "5" ) ;
278+ memoryCache . Get ( "6" ) ;
279+
280+ memoryCache . Get ( "1" ) ;
281+ memoryCache . Get ( "2" ) ;
282+ memoryCache . Get ( "3" ) ;
283+ memoryCache . Get ( "4" ) ;
284+ memoryCache . Get ( "5" ) ;
285+ memoryCache . Get ( "6" ) ;
286+
287+ memoryCache . Get ( "1" ) ;
288+ memoryCache . Get ( "2" ) ;
289+ memoryCache . Get ( "3" ) ;
290+ memoryCache . Get ( "4" ) ;
291+ memoryCache . Get ( "5" ) ;
292+ memoryCache . Get ( "6" ) ;
293+
294+ memoryCache . Get ( "1" ) ;
295+ memoryCache . Get ( "2" ) ;
296+ memoryCache . Get ( "3" ) ;
297+ memoryCache . Get ( "4" ) ;
298+ memoryCache . Get ( "5" ) ;
299+ memoryCache . Get ( "6" ) ;
300+ }
233301 }
234302}
0 commit comments