From d90dcf696d5043ad9cbfa1de5151a70d18be90b9 Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Wed, 8 Nov 2023 15:34:09 +0100 Subject: [PATCH] feat: add tests for data caching --- Benchmarks/BinaryConversionBenchmarks.cs | 8 +-- Benchmarks/DataCacheBenchmark.cs | 85 ++++++++++++++++++++++++ Benchmarks/GenericConfig.cs | 38 +++++++++++ 3 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 Benchmarks/DataCacheBenchmark.cs create mode 100644 Benchmarks/GenericConfig.cs diff --git a/Benchmarks/BinaryConversionBenchmarks.cs b/Benchmarks/BinaryConversionBenchmarks.cs index 74cef4c..3252171 100644 --- a/Benchmarks/BinaryConversionBenchmarks.cs +++ b/Benchmarks/BinaryConversionBenchmarks.cs @@ -2,16 +2,10 @@ namespace Benchmarks; using System.Security.Cryptography; using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; -[SimpleJob(RuntimeMoniker.Net80)] -[SimpleJob(RuntimeMoniker.Net70)] -[SimpleJob(RuntimeMoniker.Net60)] [Orderer(SummaryOrderPolicy.FastestToSlowest)] -[RankColumn] -[MemoryDiagnoser] -[ThreadingDiagnoser] +[Config(typeof(GenericConfig))] public class BinaryConversionBenchmarks { private byte[] _data = null!; diff --git a/Benchmarks/DataCacheBenchmark.cs b/Benchmarks/DataCacheBenchmark.cs new file mode 100644 index 0000000..27e78b4 --- /dev/null +++ b/Benchmarks/DataCacheBenchmark.cs @@ -0,0 +1,85 @@ +using System.Collections.Concurrent; +using System.Collections.Immutable; + +namespace Benchmarks; + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Order; + +[Config(typeof(GenericConfig))] +[Orderer(SummaryOrderPolicy.FastestToSlowest)] +public class DataCacheBenchmark +{ + [Params(1000, 100000, 1000000)] public int N; + private HashSet _hashSet; + private Dictionary _dictionary; + private ConcurrentDictionary _concurrentDictionary; + private ImmutableHashSet _immutableHashSet; + + [GlobalSetup] + public void Setup() + { + _hashSet = new HashSet(); + _dictionary = new Dictionary(); + _concurrentDictionary = new ConcurrentDictionary(); + _immutableHashSet = ImmutableHashSet.Empty; + + _hashSet.Clear(); + _dictionary.Clear(); + _concurrentDictionary.Clear(); + _immutableHashSet = _immutableHashSet.Clear(); + _hashSet.EnsureCapacity(N); + _dictionary.EnsureCapacity(N); + + for (var i = 0; i < N; i++) + { + _immutableHashSet = _immutableHashSet.Add(i); + _hashSet.Add(i); + _dictionary.Add(i, i); + _concurrentDictionary.TryAdd(i, i); + } + } + + [Benchmark] + public void HashSetAdd() + { + ParallelEnumerable.Range(0, N).AsParallel().ForAll(i => _hashSet.Add(i)); + } + + [Benchmark] + public void DictionaryAdd() + { + ParallelEnumerable.Range(0, N).AsParallel().ForAll(i => _dictionary.Add(N + i, i)); + } + + [Benchmark] + public void ConcurrentDictionaryAddOrUpdate() + { + ParallelEnumerable.Range(0, N).AsParallel().ForAll(i => + _concurrentDictionary.AddOrUpdate(N + i, i, (key, oldValue) => oldValue + i)); + } + + [Benchmark] + public void ImmutableHashSetLookup() + { + ParallelEnumerable.Range(0, N).AsParallel().ForAll(i => _immutableHashSet.Contains(i)); + } + + [Benchmark] + public void HashSetLookup() + { + ParallelEnumerable.Range(0, N).AsParallel().ForAll(i => _hashSet.Contains(i)); + } + + [Benchmark] + public void DictionaryLookup() + { + ParallelEnumerable.Range(0, N).AsParallel().ForAll(i => _dictionary.ContainsKey(i)); + } + + [Benchmark] + public void ConcurrentDictionaryLookup() + { + ParallelEnumerable.Range(0, N).AsParallel().ForAll(i => _concurrentDictionary.ContainsKey(i)); + } +} diff --git a/Benchmarks/GenericConfig.cs b/Benchmarks/GenericConfig.cs new file mode 100644 index 0000000..0dd812e --- /dev/null +++ b/Benchmarks/GenericConfig.cs @@ -0,0 +1,38 @@ +using BenchmarkDotNet.Analysers; +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Environments; +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Exporters.Csv; +using BenchmarkDotNet.Jobs; + +namespace Benchmarks; + +public class GenericConfig : ManualConfig +{ + public GenericConfig() + { + AddJob(Job.Default + .WithRuntime(CoreRuntime.Core80)) + .AddDiagnoser(ThreadingDiagnoser.Default, MemoryDiagnoser.Default, + EventPipeProfiler.Default) + .AddAnalyser(MinIterationTimeAnalyser.Default, OutliersAnalyser.Default, + RuntimeErrorAnalyser.Default, EnvironmentAnalyser.Default) + .AddColumn(RankColumn.Arabic).AddExporter(CsvExporter.Default, MarkdownExporter.Default); + AddJob(Job.Default + .WithRuntime(CoreRuntime.Core70)) + .AddDiagnoser(ThreadingDiagnoser.Default, MemoryDiagnoser.Default, + EventPipeProfiler.Default) + .AddAnalyser(MinIterationTimeAnalyser.Default, OutliersAnalyser.Default, + RuntimeErrorAnalyser.Default, EnvironmentAnalyser.Default) + .AddColumn(RankColumn.Arabic).AddExporter(CsvExporter.Default, MarkdownExporter.Default); + AddJob(Job.Default + .WithRuntime(CoreRuntime.Core60)) + .AddDiagnoser(ThreadingDiagnoser.Default, MemoryDiagnoser.Default, + EventPipeProfiler.Default) + .AddAnalyser(MinIterationTimeAnalyser.Default, OutliersAnalyser.Default, + RuntimeErrorAnalyser.Default, EnvironmentAnalyser.Default) + .AddColumn(RankColumn.Arabic).AddExporter(CsvExporter.Default, MarkdownExporter.Default); + } +}