Friday, August 07, 2009

.Net Collections Lookup Performance



using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;

namespace TechNoir.NorCal.BL.Tests
{
[TestFixture]
public class PerformanceTests
{
[Test]
public void CompareLookupSpeed()
{
bool warmUp = true;

for (int j = 1; j <= 10; j++)
{
int n = j * 1000;

Console.WriteLine("\nTest {0}; n = {1}\n", j, n);

List<int> list;
Dictionary<int, object> dictionary;
List<int> sortedList;
IQueryable<int> queryable;

PrepareTestData(n,
out list, out dictionary, out sortedList, out queryable);


DateTime start = DateTime.Now;
foreach (int item in list)
{
Assert.That(dictionary.ContainsKey(item));
}
DateTime end = DateTime.Now;

Console.WriteLine("IDictionary.ContainsKey : "
+ (end - start).TotalMilliseconds);


start = DateTime.Now;
foreach (int item in list)
{
Assert.That(sortedList.BinarySearch(item) != -1);
}
end = DateTime.Now;

Console.WriteLine("List.BinarySearch : "
+ (end - start).TotalMilliseconds);


start = DateTime.Now;
foreach (var item in list)
{
Assert.That(list.Contains(item));
}
end = DateTime.Now;

Console.WriteLine("List.Contains : "
+ (end - start).TotalMilliseconds);


start = DateTime.Now;
if (j <= 3)
{
foreach (int item in list)
{
int localItem = item;
Assert.That(queryable.Any(i => i == localItem));
}
}
end = DateTime.Now;

Console.WriteLine("IQueryable.Any : "
+ (end - start).TotalMilliseconds);


if (warmUp)
{
warmUp = false;
j--;
}

}
}

private static void PrepareTestData(
int n,
out List<int> list,
out Dictionary<int, object> dictionary,
out List<int> sortedList,
out IQueryable<int> queryable)
{
list = new List<int>();

var rand = new Random(42);

for (int i = 0; i < n; i++)
{
int x;
do
{
x = rand.Next(int.MaxValue);
} while (list.Contains(x));

list.Add(x);
}

queryable = list.AsQueryable();

dictionary = new Dictionary<int, object>();

foreach (var item in list)
{
dictionary.Add(item, null);
}


sortedList = new List<int>();
sortedList.AddRange(list);

sortedList.Sort();
}
}
}