55using Microsoft . Extensions . Caching . Memory ;
66using Polly . Caching ;
77
8- namespace Polly . Benchmarks
8+ namespace Polly . Benchmarks ;
9+
10+ [ Config ( typeof ( PollyConfig ) ) ]
11+ public class Cache
912{
10- [ Config ( typeof ( PollyConfig ) ) ]
11- public class Cache
13+ private static readonly MemoryCache MemoryCache = new MemoryCache ( new MemoryCacheOptions ( ) ) ;
14+ private static readonly MemoryCacheProvider CacheProvider = new MemoryCacheProvider ( MemoryCache ) ;
15+
16+ private static readonly Policy SyncPolicyMiss = Policy . Cache ( CacheProvider , TimeSpan . Zero ) ;
17+ private static readonly AsyncPolicy AsyncPolicyMiss = Policy . CacheAsync ( CacheProvider , TimeSpan . Zero ) ;
18+
19+ private static readonly Policy SyncPolicyHit = Policy . Cache ( CacheProvider , TimeSpan . MaxValue ) ;
20+ private static readonly AsyncPolicy AsyncPolicyHit = Policy . CacheAsync ( CacheProvider , TimeSpan . MaxValue ) ;
21+
22+ private static readonly Context HitContext = new Context ( nameof ( HitContext ) ) ;
23+ private static readonly Context MissContext = new Context ( nameof ( MissContext ) ) ;
24+
25+ [ GlobalSetup ]
26+ public async Task GlobalSetup ( )
1227 {
13- private static readonly MemoryCache MemoryCache = new MemoryCache ( new MemoryCacheOptions ( ) ) ;
14- private static readonly MemoryCacheProvider CacheProvider = new MemoryCacheProvider ( MemoryCache ) ;
28+ SyncPolicyHit . Execute ( ( context ) => GetObject ( ) , HitContext ) ;
29+ await AsyncPolicyHit . ExecuteAsync ( ( context , token ) => GetObjectAsync ( token ) , HitContext , CancellationToken . None ) ;
30+ }
1531
16- private static readonly Policy SyncPolicyMiss = Policy . Cache ( CacheProvider , TimeSpan . Zero ) ;
17- private static readonly AsyncPolicy AsyncPolicyMiss = Policy . CacheAsync ( CacheProvider , TimeSpan . Zero ) ;
32+ [ Benchmark ]
33+ public object Cache_Synchronous_Hit ( )
34+ {
35+ return SyncPolicyHit . Execute ( ( context ) => GetObject ( ) , HitContext ) ;
36+ }
1837
19- private static readonly Policy SyncPolicyHit = Policy . Cache ( CacheProvider , TimeSpan . MaxValue ) ;
20- private static readonly AsyncPolicy AsyncPolicyHit = Policy . CacheAsync ( CacheProvider , TimeSpan . MaxValue ) ;
38+ [ Benchmark ]
39+ public async Task < object > Cache_Asynchronous_Hit ( )
40+ {
41+ return await AsyncPolicyHit . ExecuteAsync ( ( context , token ) => GetObjectAsync ( token ) , HitContext , CancellationToken . None ) ;
42+ }
2143
22- private static readonly Context HitContext = new Context ( nameof ( HitContext ) ) ;
23- private static readonly Context MissContext = new Context ( nameof ( MissContext ) ) ;
44+ [ Benchmark ]
45+ public object Cache_Synchronous_Miss ( )
46+ {
47+ return SyncPolicyMiss . Execute ( ( context ) => GetObject ( ) , MissContext ) ;
48+ }
2449
25- [ GlobalSetup ]
26- public async Task GlobalSetup ( )
27- {
28- SyncPolicyHit . Execute ( ( context ) => GetObject ( ) , HitContext ) ;
29- await AsyncPolicyHit . ExecuteAsync ( ( context , token ) => GetObjectAsync ( token ) , HitContext , CancellationToken . None ) ;
30- }
50+ [ Benchmark ]
51+ public async Task < object > Cache_Asynchronous_Miss ( )
52+ {
53+ return await AsyncPolicyMiss . ExecuteAsync ( ( context , token ) => GetObjectAsync ( token ) , MissContext , CancellationToken . None ) ;
54+ }
3155
32- [ Benchmark ]
33- public object Cache_Synchronous_Hit ( )
34- {
35- return SyncPolicyHit . Execute ( ( context ) => GetObject ( ) , HitContext ) ;
36- }
56+ private static object GetObject ( ) => new object ( ) ;
3757
38- [ Benchmark ]
39- public async Task < object > Cache_Asynchronous_Hit ( )
40- {
41- return await AsyncPolicyHit . ExecuteAsync ( ( context , token ) => GetObjectAsync ( token ) , HitContext , CancellationToken . None ) ;
42- }
58+ private static Task < object > GetObjectAsync ( CancellationToken cancellationToken ) => Task . FromResult ( new object ( ) ) ;
4359
44- [ Benchmark ]
45- public object Cache_Synchronous_Miss ( )
60+ private sealed class MemoryCacheProvider : ISyncCacheProvider , IAsyncCacheProvider
61+ {
62+ private readonly IMemoryCache _cache ;
63+
64+ public MemoryCacheProvider ( IMemoryCache memoryCache )
4665 {
47- return SyncPolicyMiss . Execute ( ( context ) => GetObject ( ) , MissContext ) ;
66+ _cache = memoryCache ;
4867 }
4968
50- [ Benchmark ]
51- public async Task < object > Cache_Asynchronous_Miss ( )
69+ public ( bool , object ) TryGet ( string key )
5270 {
53- return await AsyncPolicyMiss . ExecuteAsync ( ( context , token ) => GetObjectAsync ( token ) , MissContext , CancellationToken . None ) ;
71+ var cacheHit = _cache . TryGetValue ( key , out var value ) ;
72+ return ( cacheHit , value ) ;
5473 }
5574
56- private static object GetObject ( ) => new object ( ) ;
57-
58- private static Task < object > GetObjectAsync ( CancellationToken cancellationToken ) => Task . FromResult ( new object ( ) ) ;
59-
60- private sealed class MemoryCacheProvider : ISyncCacheProvider , IAsyncCacheProvider
75+ public void Put ( string key , object value , Ttl ttl )
6176 {
62- private readonly IMemoryCache _cache ;
63-
64- public MemoryCacheProvider ( IMemoryCache memoryCache )
65- {
66- _cache = memoryCache ;
67- }
77+ var remaining = DateTimeOffset . MaxValue - DateTimeOffset . UtcNow ;
78+ var options = new MemoryCacheEntryOptions ( ) ;
6879
69- public ( bool , object ) TryGet ( string key )
80+ if ( ttl . SlidingExpiration )
7081 {
71- var cacheHit = _cache . TryGetValue ( key , out var value ) ;
72- return ( cacheHit , value ) ;
82+ options . SlidingExpiration = ttl . Timespan < remaining ? ttl . Timespan : remaining ;
7383 }
74-
75- public void Put ( string key , object value , Ttl ttl )
84+ else
7685 {
77- var remaining = DateTimeOffset . MaxValue - DateTimeOffset . UtcNow ;
78- var options = new MemoryCacheEntryOptions ( ) ;
79-
80- if ( ttl . SlidingExpiration )
86+ if ( ttl . Timespan == TimeSpan . MaxValue )
8187 {
82- options . SlidingExpiration = ttl . Timespan < remaining ? ttl . Timespan : remaining ;
88+ options . AbsoluteExpiration = DateTimeOffset . MaxValue ;
8389 }
8490 else
8591 {
86- if ( ttl . Timespan == TimeSpan . MaxValue )
87- {
88- options . AbsoluteExpiration = DateTimeOffset . MaxValue ;
89- }
90- else
91- {
92- options . AbsoluteExpirationRelativeToNow = ttl . Timespan < remaining ? ttl . Timespan : remaining ;
93- }
92+ options . AbsoluteExpirationRelativeToNow = ttl . Timespan < remaining ? ttl . Timespan : remaining ;
9493 }
95-
96- _cache . Set ( key , value , options ) ;
9794 }
9895
99- public Task < ( bool , object ) > TryGetAsync ( string key , CancellationToken cancellationToken , bool continueOnCapturedContext )
100- {
101- return Task . FromResult ( TryGet ( key ) ) ;
102- }
96+ _cache . Set ( key , value , options ) ;
97+ }
10398
104- public Task PutAsync ( string key , object value , Ttl ttl , CancellationToken cancellationToken , bool continueOnCapturedContext )
105- {
106- Put ( key , value , ttl ) ;
107- return Task . CompletedTask ;
108- }
99+ public Task < ( bool , object ) > TryGetAsync ( string key , CancellationToken cancellationToken , bool continueOnCapturedContext )
100+ {
101+ return Task . FromResult ( TryGet ( key ) ) ;
102+ }
103+
104+ public Task PutAsync ( string key , object value , Ttl ttl , CancellationToken cancellationToken , bool continueOnCapturedContext )
105+ {
106+ Put ( key , value , ttl ) ;
107+ return Task . CompletedTask ;
109108 }
110109 }
111- }
110+ }
0 commit comments