Skip to content

Instantly share code, notes, and snippets.

@John-Paul-R
Last active February 3, 2022 19:10
Show Gist options
  • Save John-Paul-R/55078ff314dd7d2115855e8279269c1b to your computer and use it in GitHub Desktop.
Save John-Paul-R/55078ff314dd7d2115855e8279269c1b to your computer and use it in GitHub Desktop.
Updated Dictionary Benchmarks
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
namespace Bench_Dictionaries
{
// See https://stackoverflow.com/questions/16612936/immutable-dictionary-vs-dictionary-vs-c5
// for original source of these benchmarks.
class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<Bench>();
}
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
public class Bench
{
private const int RandSeed = 826528;
private const int BenchmarkAccessCount = 1000;
[Params(100, 1000, 10000, 100000)]
public int MaxItems { get; set; }
private ReadOnlyDictionary<string, object> _dictionary = null!;
private ReadOnlyDictionary<string, object> _concurrentDictionary = null!;
private ImmutableDictionary<string, object> _immutableDictionary = null!;
private string[] _randomKeys = null!;
[GlobalSetup]
public void GlobalSetup()
{
var keyValuePairs = Enumerable.Range(0, MaxItems)
.Select(i => new KeyValuePair<string, object>(i.ToString(), i))
.ToList();
// Init Dictionaries
_immutableDictionary = keyValuePairs.ToImmutableDictionary();
// ImmutableDictionary.CreateRange<string, object>();
_dictionary = new ReadOnlyDictionary<string, object>(
new Dictionary<string, object>(keyValuePairs));
_concurrentDictionary = new ReadOnlyDictionary<string, object>(
new ConcurrentDictionary<string, object>(keyValuePairs));
// Init keys to access in benchmarks
var r = new Random(RandSeed);
_randomKeys = Enumerable.Range(0, BenchmarkAccessCount)
.Select(i => r.Next(MaxItems).ToString())
.ToArray();
}
[Benchmark]
public void BaseDictionary()
{
foreach (var key in _randomKeys) {
_dictionary.TryGetValue(key, out var value);
}
}
[Benchmark]
public void ConcurrentDictionary()
{
foreach (var key in _randomKeys) {
_concurrentDictionary.TryGetValue(key, out var value);
}
}
[Benchmark]
public void ImmutableDictionaryT()
{
foreach (var key in _randomKeys) {
_immutableDictionary.TryGetValue(key, out var value);
}
}
}
}

See Charts

BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19042.1466 (20H2/October2020Update)
AMD Ryzen Threadripper 2920X, 1 CPU, 24 logical and 12 physical cores
.NET SDK=6.0.100
  [Host]        : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT
  .NET 6.0      : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
  .NET Core 3.1 : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT
Method Job Runtime MaxItems Mean Error StdDev
BaseDictionary .NET 6.0 .NET 6.0 100 28.17 us 0.319 us 0.283 us
ConcurrentDictionary .NET 6.0 .NET 6.0 100 19.56 us 0.289 us 0.270 us
ImmutableDictionaryT .NET 6.0 .NET 6.0 100 49.82 us 0.115 us 0.090 us
BaseDictionary .NET Core 3.1 .NET Core 3.1 100 36.88 us 0.135 us 0.120 us
ConcurrentDictionary .NET Core 3.1 .NET Core 3.1 100 25.57 us 0.222 us 0.185 us
ImmutableDictionaryT .NET Core 3.1 .NET Core 3.1 100 58.79 us 0.249 us 0.233 us
BaseDictionary .NET 6.0 .NET 6.0 1000 24.44 us 0.481 us 0.625 us
ConcurrentDictionary .NET 6.0 .NET 6.0 1000 26.47 us 0.489 us 0.458 us
ImmutableDictionaryT .NET 6.0 .NET 6.0 1000 66.43 us 0.248 us 0.194 us
BaseDictionary .NET Core 3.1 .NET Core 3.1 1000 32.54 us 0.181 us 0.169 us
ConcurrentDictionary .NET Core 3.1 .NET Core 3.1 1000 31.40 us 0.243 us 0.190 us
ImmutableDictionaryT .NET Core 3.1 .NET Core 3.1 1000 77.94 us 0.431 us 0.404 us
BaseDictionary .NET 6.0 .NET 6.0 10000 30.68 us 0.595 us 0.685 us
ConcurrentDictionary .NET 6.0 .NET 6.0 10000 26.26 us 0.256 us 0.239 us
ImmutableDictionaryT .NET 6.0 .NET 6.0 10000 100.70 us 0.724 us 0.604 us
BaseDictionary .NET Core 3.1 .NET Core 3.1 10000 35.45 us 0.205 us 0.181 us
ConcurrentDictionary .NET Core 3.1 .NET Core 3.1 10000 36.78 us 0.672 us 0.628 us
ImmutableDictionaryT .NET Core 3.1 .NET Core 3.1 10000 106.51 us 0.708 us 0.628 us
BaseDictionary .NET 6.0 .NET 6.0 100000 36.74 us 0.253 us 0.224 us
ConcurrentDictionary .NET 6.0 .NET 6.0 100000 49.94 us 0.352 us 0.329 us
ImmutableDictionaryT .NET 6.0 .NET 6.0 100000 161.21 us 0.714 us 0.633 us
BaseDictionary .NET Core 3.1 .NET Core 3.1 100000 42.55 us 0.458 us 0.428 us
ConcurrentDictionary .NET Core 3.1 .NET Core 3.1 100000 54.18 us 0.371 us 0.310 us
ImmutableDictionaryT .NET Core 3.1 .NET Core 3.1 100000 176.20 us 2.040 us 1.808 us
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment