If you are looking to store a bunch of elements in collections in .NET you will find that there are many options - some less popular than others and the question is which to choose. The .NET
library is similar to Java
's library where a bunch of stuff just gets added in every version, some of which does not necessarily bring anything new or is used in rare cases. These benchmarks test various collections available in .NET and show the relative performance between each type of collection.
The following collections are tested:
List
ArrayList
LinkedList
HashSet
The plots are on a logarithmic scale from to elements with samples per test.
It seems that HashSet
out-performs any other collection with just a slight overhead on inserting elements. For large collections with many elements where looping over the set of elements is a reoccurring programming pattern used in the code, then HashSet
should always be used since it performs great by comparison to other collections.
using System; using System.Collections.Generic; using System.Collections; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using System.Text; namespace ListsBenchmark { class Program { private static readonly string[] Letters = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; private static class Result { public static List<long> ElapsedList = new List<long>(); public static List<long> ElapsedArrayList = new List<long>(); public static List<long> ElapsedLinkedList = new List<long>(); public static List<long> ElapsedHashSet = new List<long>(); } private static class MemoryResult { public static List<long> ListMemory = new List<long>(); public static List<long> ArrayListMemory = new List<long>(); public static List<long> LinkedListMemory = new List<long>(); public static List<long> HashSetMemory = new List<long>(); } static void Main(string[] args) { const int elements = 1000; const int trials = 10000; ArrayList listArray = new ArrayList(); List<string> listList = new List<string>(); LinkedList<string> listLinked = new LinkedList<string>(); HashSet<string> listHashSet = new HashSet<string>(); Console.WriteLine("------------------- Running Insert -------------------------"); for (int j = 0; j < trials; ++j) { long memoryStart = System.GC.GetTotalMemory(true); Stopwatch watch = Stopwatch.StartNew(); for (int i = 0; i < elements; ++i) { listList.Add(GetRandomLetter()); } watch.Stop(); Result.ElapsedList.Add(watch.Elapsed.Ticks); MemoryResult.ListMemory.Add(System.GC.GetTotalMemory(true) - memoryStart); memoryStart = System.GC.GetTotalMemory(true); watch = Stopwatch.StartNew(); for (int i = 0; i < elements; ++i) { listArray.Add(GetRandomLetter()); } watch.Stop(); Result.ElapsedArrayList.Add(watch.Elapsed.Ticks); MemoryResult.ArrayListMemory.Add(System.GC.GetTotalMemory(true) - memoryStart); memoryStart = System.GC.GetTotalMemory(true); watch = Stopwatch.StartNew(); for (int i = 0; i < elements; ++i) { listLinked.AddLast(GetRandomLetter()); } watch.Stop(); Result.ElapsedLinkedList.Add(watch.Elapsed.Ticks); MemoryResult.LinkedListMemory.Add(System.GC.GetTotalMemory(true) - memoryStart); memoryStart = System.GC.GetTotalMemory(true); watch = Stopwatch.StartNew(); for (int i = 0; i < elements; ++i) { listHashSet.Add(GetRandomLetter()); } watch.Stop(); Result.ElapsedHashSet.Add(watch.Elapsed.Ticks); MemoryResult.HashSetMemory.Add(System.GC.GetTotalMemory(true) - memoryStart); } Console.WriteLine("----------------------- Insert -----------------------------"); Console.WriteLine("Insert Average List: " + Result.ElapsedList.Average() + " Memory: " + MemoryResult.ListMemory.Average()); Console.WriteLine("Insert Average ArrayList: " + Result.ElapsedArrayList.Average() + " Memory: " + MemoryResult.ArrayListMemory.Average()); Console.WriteLine("Insert Average LinkedList: " + Result.ElapsedLinkedList.Average() + " Memory: " + MemoryResult.LinkedListMemory.Average()); Console.WriteLine("Insert Average HashSet: " + Result.ElapsedHashSet.Average() + " Memory: " + MemoryResult.HashSetMemory.Average()); Console.WriteLine("------------------------------------------------------------"); Result.ElapsedList.Clear(); Result.ElapsedArrayList.Clear(); Result.ElapsedLinkedList.Clear(); Result.ElapsedHashSet.Clear(); Console.WriteLine("------------------- Running Access -------------------------"); for (int j = 0; j < trials; ++j) { Stopwatch watch = Stopwatch.StartNew(); object access = listList[elements - 1]; watch.Stop(); Result.ElapsedList.Add(watch.Elapsed.Ticks); watch = Stopwatch.StartNew(); access = listArray[elements - 1]; watch.Stop(); Result.ElapsedArrayList.Add(watch.Elapsed.Ticks); watch = Stopwatch.StartNew(); access = listLinked.Last; watch.Stop(); Result.ElapsedLinkedList.Add(watch.Elapsed.Ticks); watch = Stopwatch.StartNew(); access = listHashSet.Last(); watch.Stop(); Result.ElapsedHashSet.Add(watch.Elapsed.Ticks); } Console.WriteLine("----------------------- Access -----------------------------"); Console.WriteLine("Insert Average List: " + Result.ElapsedList.Average()); Console.WriteLine("Insert Average ArrayList: " + Result.ElapsedArrayList.Average()); Console.WriteLine("Insert Average LinkedList: " + Result.ElapsedLinkedList.Average()); Console.WriteLine("Insert Average HashSet: " + Result.ElapsedHashSet.Average()); Console.WriteLine("------------------------------------------------------------"); Result.ElapsedList.Clear(); Result.ElapsedArrayList.Clear(); Result.ElapsedLinkedList.Clear(); Result.ElapsedHashSet.Clear(); Console.WriteLine("------------------- Running ForEach -------------------------"); for (int j = 0; j < trials; ++j) { Stopwatch watch = Stopwatch.StartNew(); foreach (var o in listList) { } watch.Stop(); Result.ElapsedList.Add(watch.Elapsed.Ticks); watch = Stopwatch.StartNew(); foreach (var o in listArray) { } watch.Stop(); Result.ElapsedArrayList.Add(watch.Elapsed.Ticks); watch = Stopwatch.StartNew(); foreach (var o in listLinked) { } watch.Stop(); Result.ElapsedLinkedList.Add(watch.Elapsed.Ticks); watch = Stopwatch.StartNew(); foreach (var o in listHashSet) { } watch.Stop(); Result.ElapsedHashSet.Add(watch.Elapsed.Ticks); } Console.WriteLine("----------------------- ForEach -----------------------------"); Console.WriteLine("ForEach Average List: " + Result.ElapsedList.Average()); Console.WriteLine("ForEach Average ArrayList: " + Result.ElapsedArrayList.Average()); Console.WriteLine("ForEach Average LinkedList: " + Result.ElapsedLinkedList.Average()); Console.WriteLine("ForEach Average HashSet: " + Result.ElapsedHashSet.Average()); Console.WriteLine("------------------------------------------------------------"); Console.ReadKey(); } private static string GetRandomLetter() { Random rand = new Random(); return Letters[rand.Next(0, Letters.Count())]; } /// <summary> /// Calculates the lenght in bytes of an object /// and returns the size /// </summary> /// <param name="TestObject"></param> /// <returns></returns> private static int GetObjectSize(object TestObject) { BinaryFormatter bf = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); byte[] Array; bf.Serialize(ms, TestObject); Array = ms.ToArray(); return Array.Length; } } }
--------------------------------------------------------------------- 1 element --------------------------------------------------------------------- ------------------- Running Insert ------------------------- ----------------------- Insert ----------------------------- Insert Average List: 80.6666 Memory: 26.7568 Insert Average ArrayList: 79.6808 Memory: 26.7456 Insert Average LinkedList: 84.192 Memory: 61.5848 Insert Average HashSet: 87.317 Memory: 37.1456 ------------------------------------------------------------ ------------------- Running Access ------------------------- ----------------------- Access ----------------------------- Insert Average List: 1.0942 Insert Average ArrayList: 1.0375 Insert Average LinkedList: 1.0914 Insert Average HashSet: 11.2685 ------------------------------------------------------------ ------------------- Running ForEach ------------------------- ----------------------- ForEach ----------------------------- ForEach Average List: 735.5143 ForEach Average ArrayList: 1297.0771 ForEach Average LinkedList: 1077.0409 ForEach Average HashSet: 4.9244 ------------------------------------------------------------ --------------------------------------------------------------------- 10 elements --------------------------------------------------------------------- ------------------- Running Insert ------------------------- ----------------------- Insert ----------------------------- Insert Average List: 334.3421 Memory: 118.2528 Insert Average ArrayList: 334.276 Memory: 118.2464 Insert Average LinkedList: 350.3893 Memory: 493.328 Insert Average HashSet: 366.8616 Memory: 37.076 ------------------------------------------------------------ ------------------- Running Access ------------------------- ----------------------- Access ----------------------------- Insert Average List: 1.0411 Insert Average ArrayList: 1.0459 Insert Average LinkedList: 1.1197 Insert Average HashSet: 11.4223 ------------------------------------------------------------ ------------------- Running ForEach ------------------------- ----------------------- ForEach ----------------------------- ForEach Average List: 7547.0454 ForEach Average ArrayList: 13121.2916 ForEach Average LinkedList: 12277.8804 ForEach Average HashSet: 12.5262 ------------------------------------------------------------ --------------------------------------------------------------------- 100 elements --------------------------------------------------------------------- ------------------- Running Insert ------------------------- ----------------------- Insert ----------------------------- Insert Average List: 2435.1778 Memory: 851.9656 Insert Average ArrayList: 2426.0889 Memory: 851.9248 Insert Average LinkedList: 2549.5733 Memory: 4813.0664 Insert Average HashSet: 2654.184 Memory: 36.8792 ------------------------------------------------------------ ------------------- Running Access ------------------------- ----------------------- Access ----------------------------- Insert Average List: 1.0362 Insert Average ArrayList: 1.027 Insert Average LinkedList: 1.0627 Insert Average HashSet: 11.2477 ------------------------------------------------------------ ------------------- Running ForEach ------------------------- ----------------------- ForEach ----------------------------- ForEach Average List: 75233.6623 ForEach Average ArrayList: 130411.8414 ForEach Average LinkedList: 141253.7191 ForEach Average HashSet: 16.5952 ------------------------------------------------------------ --------------------------------------------------------------------- 1000 elements --------------------------------------------------------------------- ------------------- Running Insert ------------------------- ----------------------- Insert ----------------------------- Insert Average List: 21925.6747 Memory: 13434.8944 Insert Average ArrayList: 21934.5563 Memory: 13434.864 Insert Average LinkedList: 22851.6237 Memory: 48013.1 Insert Average HashSet: 23709.6228 Memory: 36.6648 ------------------------------------------------------------ ------------------- Running Access ------------------------- ----------------------- Access ----------------------------- Insert Average List: 1.0346 Insert Average ArrayList: 1.0336 Insert Average LinkedList: 1.0308 Insert Average HashSet: 11.1237 ------------------------------------------------------------ ------------------- Running ForEach ------------------------- ----------------------- ForEach ----------------------------- ForEach Average List: 759440.6768 ForEach Average ArrayList: 1264129.9651 ForEach Average LinkedList: 1364752.2826 ForEach Average HashSet: 16.8205 ------------------------------------------------------------
The following collections are tested:
Dictionary
SortedDictionary
Hashtable
SortedList
HybridDictionary
The plots are on a logarithmic scale from to elements with samples per test.
Overall, SortedList
gives a better memory performance at the expense of lookup time. HybridDictionary
seems completely useless compared to Hashtable
- also, Hashtable
seems to beat the Dictionary
collection in every other aspect (even for a small number of elements).
The code used for the benchmark is based on Vladimir Bodurov's blog with some modifications.
using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; /* to compile enter in the command prompt: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc IDictTest.cs to run enter in the command prompt: IDictTest */ using System.Linq; namespace IDictTest { public class RunResult { public decimal MemoryUsed; public decimal InsertTicks; public decimal SearchTicks; public decimal ForEachTicks; } public class Program { private static int SearchIndex = 27; //private const int NumberInsertedKeys = 1; //private const int NumberInsertedKeys = 10; //private const int NumberInsertedKeys = 100; //private const int NumberInsertedKeys = 1000; private const int NumberInsertedKeys = 10000; private const int NumberTests = 10000; private static readonly string[] Letters = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" }; public static void Main(string[] args) { /*try {*/ // TRY STARTS HERE ---------- List<RunResult> listDictionary = new List<RunResult>(); List<RunResult> listSortedDictionary = new List<RunResult>(); List<RunResult> listHashtable = new List<RunResult>(); List<RunResult> listSorderList = new List<RunResult>(); List<RunResult> listHybridDictionary = new List<RunResult>(); Stopwatch watch = Stopwatch.StartNew(); for (int i = 0; i < NumberTests; i++) { SearchIndex += 1; //Random rand = new Random(); //int randInt = rand.Next(0, 5); //if (randInt == 0) //{ listDictionary.Add( Test("Dictionary", new Dictionary<string, string>(), i)); //} //else if (randInt == 1) //{ listSortedDictionary.Add( Test("SortedDictionary", new SortedDictionary<string, string>(), i)); //} //else if (randInt == 2) //{ listHashtable.Add( Test("Hashtable", new Hashtable(), i)); //} //else if (randInt == 3) //{ listSorderList.Add( Test("SortedList", new SortedList(), i)); //} //else if (randInt == 4) //{ listHybridDictionary.Add( Test("HybridDictionary", new HybridDictionary(), i)); //} } Console.Clear(); Msg("Time taken (minutes): {0} or about {1} minutes and {2} seconds", watch.Elapsed.TotalMinutes, watch.Elapsed.Minutes, watch.Elapsed.Seconds); RunResult resultDict = CalculateAvg(listDictionary); RunResult resultSortDict = CalculateAvg(listSortedDictionary); RunResult resultHash = CalculateAvg(listHashtable); RunResult resultSortList = CalculateAvg(listSorderList); RunResult resultHybridDictionary = CalculateAvg(listHybridDictionary); RunResult min = new RunResult { MemoryUsed = MinDecimal(new List<decimal> {resultDict.MemoryUsed, resultSortDict.MemoryUsed, resultHash.MemoryUsed, resultSortList.MemoryUsed, resultHybridDictionary.MemoryUsed}), InsertTicks = MinDecimal(new List<decimal> {resultDict.InsertTicks, resultSortDict.InsertTicks, resultHash.InsertTicks, resultSortList.InsertTicks, resultHybridDictionary.InsertTicks}), SearchTicks = MinDecimal(new List<decimal> {resultDict.SearchTicks, resultSortDict.SearchTicks, resultHash.SearchTicks, resultSortList.SearchTicks, resultHybridDictionary.SearchTicks}), ForEachTicks = MinDecimal(new List<decimal> {resultDict.ForEachTicks, resultSortDict.ForEachTicks, resultHash.ForEachTicks, resultSortList.ForEachTicks, resultHybridDictionary.ForEachTicks}) }; // print the results PrintResults(resultDict, listDictionary.Count, min, "Dictionary"); PrintResults(resultSortDict, listDictionary.Count, min, "SortedDictionary"); PrintResults(resultHash, listDictionary.Count, min, "Hashtable"); PrintResults(resultSortList, listDictionary.Count, min, "SortedList"); PrintResults(resultHybridDictionary, listHybridDictionary.Count, min, "HybridDictionary"); Console.ReadKey(); // TRY ENDS HERE ---------- /*} catch (Exception ex) { Msg("{0}", ex); }*/ } private static decimal MinDecimal(IEnumerable<decimal> values) { return values.Min(); } private static RunResult CalculateAvg(List<RunResult> list) { decimal sumMemory = 0; decimal sumInsert = 0; decimal sumSearch = 0; decimal sumForEach = 0; for (int i = 0; i < list.Count; i++) { RunResult curr = list[i]; sumMemory += curr.MemoryUsed; sumInsert += curr.InsertTicks; sumSearch += curr.SearchTicks; sumForEach += curr.ForEachTicks; // uncomment to print each line //Msg("{0,11} {1,13} {2,14}", //curr.MemoryUsed, curr.InsertTicks, curr.SearchTicks); } return new RunResult { MemoryUsed = sumMemory / list.Count, InsertTicks = sumInsert / list.Count, SearchTicks = sumSearch / list.Count, ForEachTicks = sumForEach / list.Count, }; } private static void PrintResults(RunResult result, int count, RunResult min, string name) { Msg("--------- Results for {0}", name); Msg("# Tests {0}", count); Msg("Memory Used Insert Ticks Search Ticks ForEach Ticks"); Msg("Average Values:"); Msg("{0,11:N} {1,13:N} {2,14:N} {3,14:N}", result.MemoryUsed, result.InsertTicks, result.SearchTicks, result.ForEachTicks); Msg("Performance Coefficient:"); Msg("{0,11:N} {1,13:N} {2,14:N} {3,14:N}", min.MemoryUsed / result.MemoryUsed, min.InsertTicks / result.InsertTicks, min.SearchTicks / result.SearchTicks, min.ForEachTicks / result.ForEachTicks); Msg(""); } private static void Msg(string name, params object[] args) { Console.WriteLine(name, args); } private static RunResult Test(string name, IDictionary dict, int n) { Console.Clear(); Msg("Currently executing test {1} of {2} for {0} object", name, n + 1, NumberTests); RunResult rr = new RunResult(); Stopwatch watch; Random rand = new Random(); long memoryStart = System.GC.GetTotalMemory(true); long insertTicksSum = 0; for (int i = 0; i < NumberInsertedKeys; i++) { string key = GetRandomLetter(rand, i) + "_key" + i; string value = "value" + i; watch = Stopwatch.StartNew(); dict.Add(key, value); watch.Stop(); insertTicksSum += watch.ElapsedTicks; } rr.MemoryUsed = System.GC.GetTotalMemory(true) - memoryStart; rr.InsertTicks = insertTicksSum; watch = Stopwatch.StartNew(); object searchResult = dict["C_key" + SearchIndex]; watch.Stop(); rr.SearchTicks = watch.ElapsedTicks; watch = Stopwatch.StartNew(); foreach (var curr in dict) { } watch.Stop(); rr.ForEachTicks = watch.ElapsedTicks; return rr; } private static string GetRandomLetter(Random rand, int i) { if (i == SearchIndex) { return "C"; } return Letters[rand.Next(0, 10)]; } } }
The raw data obtained is the following:
--------------------------------------------------------------------- 1 element --------------------------------------------------------------------- Time taken (minutes): 1.79397254 or about 1 minutes and 47 seconds --------- Results for Dictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 256.10 24.84 36.39 23.78 Performance Coefficient: 0.47 0.49 0.86 0.57 --------- Results for SortedDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 176.11 29.82 65.88 64.52 Performance Coefficient: 0.68 0.41 0.47 0.21 --------- Results for Hashtable # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 120.09 12.26 31.20 13.55 Performance Coefficient: 1.00 1.00 1.00 1.00 --------- Results for SortedList # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 440.12 21.19 47.45 15.23 Performance Coefficient: 0.27 0.58 0.66 0.89 --------- Results for HybridDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 208.12 12.47 31.70 18.71 Performance Coefficient: 0.58 0.98 0.98 0.72 --------------------------------------------------------------------- 10 elements --------------------------------------------------------------------- Time taken (minutes): 1.81806457333333 or about 1 minutes and 49 seconds --------- Results for Dictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,368.25 62.85 36.21 28.47 Performance Coefficient: 0.82 0.58 0.88 0.73 --------- Results for SortedDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,400.21 148.45 63.61 89.11 Performance Coefficient: 0.81 0.24 0.50 0.23 --------- Results for Hashtable # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,128.18 36.20 31.93 20.72 Performance Coefficient: 1.00 1.00 1.00 1.00 --------- Results for SortedList # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,160.20 96.19 47.09 21.33 Performance Coefficient: 0.97 0.38 0.68 0.97 --------- Results for HybridDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,504.14 58.08 32.97 21.48 Performance Coefficient: 0.75 0.62 0.97 0.96 --------------------------------------------------------------------- 100 elements --------------------------------------------------------------------- Time taken (minutes): 2.04033235333333 or about 2 minutes and 2 seconds --------- Results for Dictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 13,609.33 400.96 48.51 93.54 Performance Coefficient: 0.75 0.98 0.82 0.73 --------- Results for SortedDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 13,641.27 1,775.00 78.89 460.23 Performance Coefficient: 0.74 0.22 0.50 0.15 --------- Results for Hashtable # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 13,513.30 394.40 39.66 83.52 Performance Coefficient: 0.75 1.00 1.00 0.81 --------- Results for SortedList # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 10,153.45 924.58 58.12 68.06 Performance Coefficient: 1.00 0.43 0.68 1.00 --------- Results for HybridDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 13,888.70 424.53 42.37 84.92 Performance Coefficient: 0.73 0.93 0.94 0.80 --------------------------------------------------------------------- 1000 elements --------------------------------------------------------------------- Time taken (minutes): 4.95599211833333 or about 4 minutes and 57 seconds --------- Results for Dictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 148,564.65 2,936.08 56.83 834.89 Performance Coefficient: 0.75 1.00 0.87 0.71 --------- Results for SortedDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 150,444.44 24,926.01 115.41 4,347.67 Performance Coefficient: 0.74 0.12 0.43 0.14 --------- Results for Hashtable # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 150,174.35 3,021.80 49.42 766.61 Performance Coefficient: 0.74 0.97 1.00 0.77 --------- Results for SortedList # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 110,892.39 12,155.85 84.25 593.47 Performance Coefficient: 1.00 0.24 0.59 1.00 --------- Results for HybridDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 150,552.46 3,106.63 51.38 764.23 Performance Coefficient: 0.74 0.95 0.96 0.78 --------------------------------------------------------------------- 10000 elements --------------------------------------------------------------------- Time taken (minutes): 30.768446505 or about 30 minutes and 46 seconds --------- Results for Dictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,449,026.85 30,397.67 95.40 7,887.38 Performance Coefficient: 0.84 1.00 0.88 0.68 --------- Results for SortedDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,518,441.25 326,215.47 172.00 41,833.80 Performance Coefficient: 0.80 0.09 0.49 0.13 --------- Results for Hashtable # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,462,729.17 35,274.21 83.66 6,688.47 Performance Coefficient: 0.83 0.86 1.00 0.80 --------- Results for SortedList # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,220,674.29 474,059.49 128.99 5,330.26 Performance Coefficient: 1.00 0.06 0.65 1.00 --------- Results for HybridDictionary # Tests 10000 Memory Used Insert Ticks Search Ticks ForEach Ticks Average Values: 1,463,106.28 34,983.80 86.18 6,751.31 Performance Coefficient: 0.83 0.87 0.97 0.79