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)); } }