Our application uses plenty of dictionaries which have multi level lookup that are not frequently changing. We are investigating at converting some of the critical code that
With .NET 3.1 they seem very similar on small amount.
| Method | MAXITEMS | Mean | Error | StdDev |
|---------- |--------- |----------:|----------:|----------:|
| imm | 10 | 0.9921 ns | 0.0630 ns | 0.1837 ns |
| scg | 10 | 0.9699 ns | 0.0571 ns | 0.1683 ns |
| scgsorted | 10 | 1.0136 ns | 0.0577 ns | 0.1684 ns |
| imm | 100 | 1.5296 ns | 0.1153 ns | 0.3327 ns |
| scg | 100 | 1.3151 ns | 0.0694 ns | 0.1990 ns |
| scgsorted | 100 | 1.4516 ns | 0.0855 ns | 0.2426 ns |
| imm | 1000 | 0.8514 ns | 0.0905 ns | 0.2582 ns |
| scg | 1000 | 1.0898 ns | 0.0552 ns | 0.1416 ns |
| scgsorted | 1000 | 1.0302 ns | 0.0533 ns | 0.1001 ns |
| imm | 10000 | 1.0280 ns | 0.0530 ns | 0.1175 ns |
| scg | 10000 | 0.9929 ns | 0.0523 ns | 0.1253 ns |
| scgsorted | 10000 | 1.0531 ns | 0.0534 ns | 0.1248 ns |
Test source code:
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
namespace CollectionsTest
{
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime;
///
///
///
public class Program
{
private static ImmutableDictionary idictionary;
private static Dictionary dictionary;
private static SortedDictionary sorteddictionary;
private static string[] randomIndexes;
[Params(10, 100, 1000, 10000)] public int MAXITEMS { get; set; }
public Program()
{
Console.WriteLine("\n# - {0}", MAXITEMS);
List accessIndex = new List(MAXITEMS);
List> listofkvps = new List>();
List> listoftuples = new List>();
for (int i = 0; i < MAXITEMS; i++)
{
listoftuples.Add(new Tuple(i.ToString(), i));
listofkvps.Add(new KeyValuePair(i.ToString(), i));
accessIndex.Add(i.ToString());
}
// Randomize for lookups
Random r = new Random(Environment.TickCount);
List randomIndexesList = new List(MAXITEMS);
while (accessIndex.Count > 0)
{
int index = r.Next(accessIndex.Count);
string value = accessIndex[index];
accessIndex.RemoveAt(index);
randomIndexesList.Add(value);
}
// Convert to array for best perf
randomIndexes = randomIndexesList.ToArray();
// LOAD ------------------------------------------------------------------------------------------------
// IMMU
idictionary = listofkvps.ToImmutableDictionary();
//Console.WriteLine(idictionary.Count);
// SCGD
dictionary = new Dictionary();
for (int i = 0; i < MAXITEMS; i++)
{
dictionary.Add(i.ToString(), i);
}
sorteddictionary = new SortedDictionary();
for (int i = 0; i < MAXITEMS; i++)
{
sorteddictionary.Add(i.ToString(), i);
}
//Console.WriteLine(dictionary.Count);
//scg(randomIndexes, dictionary);
//imm(randomIndexes, idictionary);
}
///
/// Mains the specified args.
///
/// The args.
public static void Main(string[] args)
{
// INIT TEST DATA ------------------------------------------------------------------------------------------------
Console.WriteLine(BenchmarkRunner.Run());
}
[Benchmark]
public void imm()
{
for (int index = 0, indexMax = randomIndexes.Length; index < indexMax; index++)
{
string i = randomIndexes[index];
object value;
idictionary.TryGetValue(i, out value);
}
}
[Benchmark]
public void scg()
{
// TEST ------------------------------------------------------------------------------------------------
for (int index = 0, indexMax = randomIndexes.Length; index < indexMax; index++)
{
string i = randomIndexes[index];
object value;
dictionary.TryGetValue(i, out value);
}
}
[Benchmark]
public void scgsorted()
{
// TEST ------------------------------------------------------------------------------------------------
for (int index = 0, indexMax = randomIndexes.Length; index < indexMax; index++)
{
string i = randomIndexes[index];
object value;
sorteddictionary.TryGetValue(i, out value);
}
}
}
}