Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
// See the LICENSE file in the project root for more information.

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Extensions;
using MicroBenchmarks;
using System;
using System.Linq;

namespace Microsoft.Extensions.Caching.Memory.Tests
{
[BenchmarkCategory(Categories.Libraries)]
public class MemoryCacheTests
{
private MemoryCache _memCache;
private (object key, object value)[] _items;

[GlobalSetup]
public void Setup()
[GlobalSetup(Targets = new[] { nameof(GetHit), nameof(TryGetValueHit), nameof(GetMiss), nameof(TryGetValueMiss), nameof(SetOverride) })]
public void SetupBasic()
{
_memCache = new MemoryCache(new MemoryCacheOptions());
for (var i = 0; i < 1024; i++)
Expand All @@ -22,8 +26,8 @@ public void Setup()
}
}

[GlobalCleanup]
public void Cleanup() => _memCache.Dispose();
[GlobalCleanup(Targets = new[] { nameof(GetHit), nameof(TryGetValueHit), nameof(GetMiss), nameof(TryGetValueMiss), nameof(SetOverride) })]
public void CleanupBasic() => _memCache.Dispose();

[Benchmark]
public object GetHit() => _memCache.Get("256");
Expand All @@ -39,5 +43,100 @@ public void Setup()

[Benchmark]
public object SetOverride() => _memCache.Set("512", "512");

[GlobalSetup(Targets = new[] { nameof(AddThenRemove_NoExpiration), nameof(AddThenRemove_AbsoluteExpiration), nameof(AddThenRemove_RelativeExpiration), nameof(AddThenRemove_SlidingExpiration) })]
public void Setup_AddThenRemove()
{
_items = ValuesGenerator.ArrayOfUniqueValues<int>(100).Select(x => ((object)x.ToString(), (object)x.ToString())).ToArray();
}

[Benchmark]
public void AddThenRemove_NoExpiration()
{
using (MemoryCache cache = new MemoryCache(new MemoryCacheOptions()))
{
foreach (var item in _items)
{
using (ICacheEntry entry = cache.CreateEntry(item.key))
{
entry.Value = item.value;
} // entry.Dispose is adding it to the cache
}

foreach (var item in _items)
{
cache.Remove(item.key);
}
}
}

[Benchmark]
public void AddThenRemove_AbsoluteExpiration()
{
DateTimeOffset absolute = DateTimeOffset.UtcNow.AddHours(1);

using (MemoryCache cache = new MemoryCache(new MemoryCacheOptions()))
{
foreach (var item in _items)
{
using (ICacheEntry entry = cache.CreateEntry(item.key))
{
entry.AbsoluteExpiration = absolute;
entry.Value = item.value;
}
}

foreach (var item in _items)
{
cache.Remove(item.key);
}
}
}

[Benchmark]
public void AddThenRemove_RelativeExpiration()
{
TimeSpan relative = TimeSpan.FromHours(1);

using (MemoryCache cache = new MemoryCache(new MemoryCacheOptions()))
{
foreach (var item in _items)
{
using (ICacheEntry entry = cache.CreateEntry(item.key))
{
entry.AbsoluteExpirationRelativeToNow = relative;
entry.Value = item.value;
}
}

foreach (var item in _items)
{
cache.Remove(item.key);
}
}
}

[Benchmark]
public void AddThenRemove_SlidingExpiration()
{
TimeSpan relative = TimeSpan.FromHours(1);

using (MemoryCache cache = new MemoryCache(new MemoryCacheOptions()))
{
foreach (var item in _items)
{
using (ICacheEntry entry = cache.CreateEntry(item.key))
{
entry.SlidingExpiration = relative;
entry.Value = item.value;
}
}

foreach (var item in _items)
{
cache.Remove(item.key);
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a SlidingExpiration test as well? The above test is for absoluteExpirationRelativeToNow AFAICT.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eerhardt we should, thanks for pointing this out! I could not find an extension method that would allow for setting SlidingExpiration so I've changed all the benchmarks to use the using pattern for adding the entries (used by the extension methods)

}
}