Scott Hanselman

Differences between Hashtable vs Dictonary vs ConcurrentDictionary vs ImmutableDictionary

September 28, 2021 Comment on this post [9] Posted in DotNetCore | Musings
Sponsored By

DictionariesI'm very much enjoying David Fowler's tweets, and since he doesn't have a blog, I will continue to share and expand on his wisdom so that it might reach a larger audience.

He had a conversation with Stephen Toub where Stephen points out that ".NET has 4 built-in dictionary/map types [and] there’s no guidance on when to use what, mostly individual documentation on each implementation."

  • Hashtable
  • Dictionary
  • ConcurrentDictionary
  • ImmutableDictionary

There is actually some good documentation on C# Collections and Data Structures here that we can compare and combine with Stephen Toub's good advice (via David) as well!

There are two main types of collections; generic collections and non-generic collections. Generic collections are type-safe at compile time. Because of this, generic collections typically offer better performance.

Definitely important to remember. Generics have been around since .NET Framework 2.0 around 15 years ago so this is a good reason to consider avoiding Hashtable and using Dictionary<> instead. Hashtable is weakly typed and while it allows you to have keys that map to different kinds of objects which may seem attractive at first, you'll need to "box" the objects up and boxing and unboxing is expensive. You'll almost always want to use Dictionary instead.

If you're accessing your collection across threads, consider the System.Collections.Concurrent namespace or using System.Collections.Immutable which is thread-safe because you'll always be working on a copy as the original collection is immutable (not modifiable).

David says this about

  • ConcurrentDictionary - "Good read speed even in the face of concurrency, but it’s a heavyweight object to create and slower to update."

Or perhaps

  • Dictionary with lock - "Poor read speed, lightweight to create and medium update speed."
  • Dictionary as immutable object - "best read speed and lightweight to create but heavy update. Copy and modify on mutation e.g. new Dictionary(old).Add(key, value)"
  • Hashtable - "Good read speed (no lock required), same-ish weight as dictionary but more expensive to mutate and no generics!"
  • ImmutableDictionary - "Poorish read speed, no locking required but more allocations require to update than a dictionary."

Another one that isn't often used but I'll add as it's good to know about is

  • KeyedCollection - Generic and ordered. Uses Dictionary and List underneath

This is great advice from David:

Use the most obvious one until it bites you. Most software engineering is like this.

Measure and test, measure and test. Good luck to you!


Sponsor: Make login Auth0’s problem. Not yours. Provide the convenient login features your customers want, like social login, multi-factor authentication, single sign-on, passwordless, and more. Get started for free.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
October 03, 2021 8:43
I was really surprised ImmutableDictionary has "poorish read speed". If anything, immutable data structures have the potential to be optimized for reading. Good thing somebody else asked it on Twitter.
October 03, 2021 9:49
What about https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1?view=net-5.0? Isn't that a generic hashtable?
October 03, 2021 14:41
HashSet isn't the generic version of Hashtable, that's Dictionary<TKey, TValue>.
October 03, 2021 15:36
Ah, you're right of course. I haven't used .net Hashtable in a long, long time, I associated it with a collection of hashes (so more what a Hashset is). But documentation clearly says it's a collection of key/value pair, so yeah, a dictionary.
October 03, 2021 15:37
There are subtle issues with Dictionary and ConcurrentDictionary. See https://aloiskraus.wordpress.com/2021/08/11/concurrent-dictionary-modification-pitfalls/ where you see with .NET Framework processes spinning in endless multithreaded loops.
October 04, 2021 3:40
Thanks for the info, Scott and David, I saw that Twitter thread and it was really useful! By the way, there is a typo in the article's title, it should say "Dictionary" instead of "Dictonary" :)
October 05, 2021 15:59
David Fowler is also my favorite sine I am a man of having a strong determination to learn .NET and c# details. Thanks for sharing his post.
October 05, 2021 20:56
Hashtable is also thread-safe. So while you take a hit because of boxing, you get thread safety for ‘free’.
October 07, 2021 14:48
Thanks for the great info man and I really appreciate your efforts.

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.