HashTable vs Dictionary<>
I’ve been using a Hashtable in my DBObject because, well, I’ve never seen any problems with it. But some people on the internet seem to hate the HashTable (something I’ve never understood.) So I decided to run my own test.
I ran two tests, one with a HashTable that uses a string as the Key vs a Dictionary<string, int> and another with the same HashTable vs Dictionary<string, object>. It seemed like the Dictionary with an object would be a better comparison because I need to store objects, not just ints.
Here is the first result:

Over all, It looks like they’re pretty equal. This span is from 1 – 100 keys at 10 key intervals. Then averaged over 100 times. This next graph is over the same number of keys
Once the advantage of not having to unbox is taken away, the Hashtable seems to preform slightly faster on average.
So I’m going to continue to use the Hashtable as long as I need the value to be an object. If I needed a specific type I’d probably go with the Dictionary.
Here is my test code so you can try it yourself/find fault.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace Hash_vs_Dict_Speed_test
{
class Program
{
static public int TIMES = 100;
static public int REPEATE = 100;
static protected Stopwatch _watch;
static protected List<TimeSpan> _hashtable_times = new List<TimeSpan>();
static protected List<TimeSpan> _dict_times = new List<TimeSpan>();
static void Main(string[] args)
{
for (int i = 0; i < REPEATE; i++)
{
//Run the tests
Console.WriteLine("HashTable");
TestHashTable();
Console.WriteLine("\nDict");
TestDictonary();
}
//Display teh Average
Console.WriteLine("\n");
Average(_hashtable_times, "HashTable");
Average(_dict_times, "Dictonary");
Console.WriteLine("\t\tPress any key to exit.");
Console.ReadKey();
}
static public void TestHashTable()
{
//Start the timer
Watch_Start();
//Create the HashTable
Hashtable table = new Hashtable();
//Add a bunch of records
for (int i = 0; i < TIMES; i++)
{
table.Add("a" + i, i);
}
//Get the Records back
for (int i = 0; i < TIMES; i++)
{
int a = (int)table["a" + i];
}
//Stop the watch
Watch_Stop(_hashtable_times);
}
static public void TestDictonary()
{
//Start the timer
Watch_Start();
//Create the HashTable
Dictionary<string, object> table = new Dictionary<string, object>();
//Add a bunch of records
for (int i = 0; i < TIMES; i++)
{
table.Add("a" + i, i);
}
//Get the Records back
for (int i = 0; i < TIMES; i++)
{
int a = (int)table["a" + i];
}
//Stop the watch
Watch_Stop(_dict_times);
}
/// <summary>
/// Start the StopWatch
/// </summary>
static void Watch_Start()
{
if (_watch == null)
{
_watch = new Stopwatch();
}
else
{
_watch.Reset();
}
_watch.Start();
}
/// <summary>
/// Stop and Log the StopWatch
/// </summary>
static void Watch_Stop(List<TimeSpan> list)
{
_watch.Stop();
//Log it for Averaging
list.Add(_watch.Elapsed);
Console.WriteLine("Time: " + String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
_watch.Elapsed.Hours,
_watch.Elapsed.Minutes,
_watch.Elapsed.Seconds,
_watch.Elapsed.Milliseconds / 10));
Console.WriteLine("Ticks: " + _watch.ElapsedTicks);
}
/// <summary>
/// Get the Average times in the list
/// </summary>
/// <param name="list"></param>
/// <param name="name"></param>
static void Average(List<TimeSpan> list, string name)
{
long ticks = 0;
foreach (TimeSpan span in list)
{
ticks += span.Ticks;
}
ticks = ticks / list.Count;
TimeSpan average = new TimeSpan(ticks);
Console.WriteLine("\n\nAverage for " + name);
Console.WriteLine("Time: " + String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
average.Hours,
average.Minutes,
average.Seconds,
average.Milliseconds / 10));
Console.WriteLine("Ticks: " + average.Ticks);
}
}
}
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
