Created
September 30, 2015 02:08
-
-
Save justinvp/fd4a78259f54e9516994 to your computer and use it in GitHub Desktop.
Dictionary<TKey, TValue> constructor microbenchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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