Skip to content

Instantly share code, notes, and snippets.

@justinvp
Created September 30, 2015 02:08
Show Gist options
  • Save justinvp/fd4a78259f54e9516994 to your computer and use it in GitHub Desktop.
Save justinvp/fd4a78259f54e9516994 to your computer and use it in GitHub Desktop.
Dictionary<TKey, TValue> constructor microbenchmark
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
public class Program
{
public static void Main()
{
const int iterations = 1000000;
int[] sizes = new[] { 0, 1, 2, 3, 4, 5, 10, 25, 50, 100 };
Measure(iterations, sizes, i => new object(), i => new object());
Measure(iterations, sizes, i => i.ToString(), i => i.ToString());
Measure(iterations, sizes, i => (long)i, i => (long)i);
Measure(iterations, sizes, i => i, i => i);
}
private static void Measure<TKey, TValue>(int iterations, int[] sizes, Func<int, TKey> keySelector, Func<int, TValue> valueSelector)
{
foreach (int size in sizes)
{
Measure("Dictionary", iterations, size, keySelector, valueSelector, d => d);
}
foreach (int size in sizes)
{
Measure("DictionarySubclass", iterations, size, keySelector, valueSelector, d => new DictionarySubclass<TKey, TValue>(d));
}
foreach (int size in sizes)
{
Measure("ReadOnlyDictionary", iterations, size, keySelector, valueSelector, d => new ReadOnlyDictionary<TKey, TValue>(d));
}
}
private static void Measure<TKey, TValue>(string name, int iterations, int size, Func<int, TKey> keySelector, Func<int, TValue> valueSelector, Func<Dictionary<TKey, TValue>, IDictionary<TKey, TValue>> factory)
{
IDictionary<TKey, TValue> dictionary = CreateDictionary(size, keySelector, valueSelector, factory);
Console.Write("\"{0}<{1},{2}>\",", name, typeof(TKey).Name, typeof(TValue).Name);
Console.Write("{0},", size);
TimeSpan elapsed = Measure(dictionary, iterations, d => new Dictionary<TKey, TValue>(d));
Console.Write(elapsed.TotalMilliseconds);
Console.WriteLine();
}
private static IDictionary<TKey, TValue> CreateDictionary<TKey, TValue>(int size, Func<int, TKey> keySelector, Func<int, TValue> valueSelector, Func<Dictionary<TKey, TValue>, IDictionary<TKey, TValue>> factory)
{
var dictionary = new Dictionary<TKey, TValue>();
if (size > 0)
{
for (int i = 0; i < size; i++)
{
dictionary.Add(keySelector(i), valueSelector(i));
}
}
return factory(dictionary);
}
private static TimeSpan Measure<TKey, TValue>(IDictionary<TKey, TValue> dictionary, int iterations, Action<IDictionary<TKey, TValue>> action)
{
// Prime
action(dictionary);
// Clean up
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < iterations; i++)
{
action(dictionary);
}
sw.Stop();
return sw.Elapsed;
}
}
public class DictionarySubclass<TKey, TValue> : Dictionary<TKey, TValue>
{
public DictionarySubclass(Dictionary<TKey, TValue> dictionary)
{
foreach (var pair in dictionary) Add(pair.Key, pair.Value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment