34

I have a scenario where-in I can use either NameValueCollection or IDictionary. But I would like to know which one will be better performance-wise.

-- Using NameValueCollection

NameValueCollection options()
{
    NameValueCollection nc = new NameValueCollection();

    nc = ....; //populate nc here

    if(sorting)
       //sort NameValueCollection nc here

    return nc;
}

-- using IDictionary

IDictionary<string, string> options()
{
    Dictionary<string, string> optionDictionary = new Dictionary<string, string>();

    optionDictionary = ....; //populate

    if(sorting)
       return new SortedDictionary<string, string>(optionDictionary);
    else
       return optionDictionary;
}
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
Ujwala Khaire
  • 574
  • 2
  • 8
  • 11

4 Answers4

32

These collection types are not exactly interchangeable: NameValueCollection allows access via integer indexes. If you don't need that functionality, you shouldn't use a NameValueCollection as indexing doesn't come "for free".

Depending on the number of strings you're looking at, I would consider either Hashtable<string, string> or IDictionary<string, string>. Krzysztof Cwalina discusses the subtleties here: http://blogs.gotdotnet.com/kcwalina/archive/2004/08/06/210297.aspx.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Justin R.
  • 23,435
  • 23
  • 108
  • 157
  • 12
    NameValueCollection also supports more than one value per key (needed for query strings, etc.). – Jason DeFontes Mar 06 '09 at 04:37
  • 16
    Not true. According to this msdn article about namevaluecollection: http://msdn.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection.aspx "Collections of this type do not preserve the ordering of element, and no particular ordering is guaranteed when enumerating the collection." – kateroh Mar 04 '11 at 18:38
9

The other advantage of IDictionary is that it's not implementation specific unlike NameValueCollection.

lomaxx
  • 113,627
  • 57
  • 144
  • 179
  • 1
    what does 'implimentation specific' mean? – Shawn Kovac Jan 22 '16 at 14:53
  • 1
    `NameValueCollection` is a concrete type. `IDictionary` is an interface. So with the interface you have more flexibility as you can use any concrete class that implements that interface. – Fred Apr 20 '16 at 14:21
5

I agree with fatcat and lomaxx (and up-voted for both answers). I would add that performance of collection types should most likely be the last consideration when choosing between collection types. Use the type that most fits your usage needs. If you are in a performance critical section of code (and most likely, you're not), then the only answer is to measure each case - don't believe the Interweb, believe the numbers.

tsimon
  • 8,362
  • 2
  • 30
  • 41
  • +1 for Interweb warning. It's a Jack Black way for being Aristotelian and promoting use of the trivium. – David Robbins Dec 28 '11 at 14:52
  • really? isn't performance the single reason why different collection types exist? otherwise we'd just be using List for everything. – Spongman Jun 08 '17 at 18:11
2

A NameValueCollection in .NET is basically what's used for QueryStrings to hold key/value pairs. The biggest difference is when two items with the same key are added. With IDictionary, there are two ways to set a value. Using the .Add() method will throw an error on a duplicate key when the key already exists. But simply setting the item equal to a value will overwrite the value. This is how IDictionary handles duplicate keys. But NameValueCollection will add values like this: "value1,value2,value3". So the existing item value gets appended with a comma, then the new value appended to it each time.

It seems to me that this NameValueCollection was built specifically for QueryString use and access. A QueryString like "?a=1&b=2&a=3" in .NET will yield a result of item["a"] = "1,3". This difference of how duplicate keys are treated is the 'real' difference, that is, the biggest difference between the two.

I suspect that a NameValueCollection also does not use any hash table for rapid access of keys when the collection is large because this access is slower for small collections than without the hash table. I have not found definitive information that states whether a NameValueCollection does or does not use a hash table to access the keys. I do know that an IDictionary uses a hash table so that accessing keys in an IDictionary with many keys is quite fast. So i suspect that a NameValueCollection is faster for small collections than an IDictionary. If my guess is correct, then it wud mean a NameValueCollection shud by no means be used for large collections since the larger it is, it massively slows down without a hash table to access the keys.

For the number of keys in a querystring, this number is normally very small, so i wud guess the NameValueCollection does not use hashes, for better performance. But if Microsoft designed things for performance, and for what's best for their users, Windows wud be so different than it is today. So we can't assume anything that 'shud be'.

Also, i want to clarify an incorrect claim by the most popularly voted answer to this question. Kateroh's comment below the incorrect answer says it well enuf, that i don't need to add anything to it. But i repeat Kateroh's comment here so just maybe more people will realize that the most popular answer is wrong. Kateroh correctly states:

Shawn Kovac
  • 1,425
  • 15
  • 17