2009-03-06 23 views
29

Tengo un escenario en el que puedo usar NameValueCollection o IDictionary. Pero me gustaría saber cuál será mejor para el rendimiento.IDictionary <cadena, cadena> o NameValueCollection

- Uso NameValueCollection

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

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

    if(sorting) 
     //sort NameValueCollection nc here 

    return nc; 
} 

- usando 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; 
} 

Respuesta

28

Estos tipos de cobro no son exactamente intercambiables: NameValueCollection permite el acceso a través de índices enteros. Si no necesita esa funcionalidad, no debe usar NameValueCollection ya que la indexación no es "gratis".

Dependiendo de la cantidad de cadenas que esté viendo, consideraría Hashtable o IDictionary. Krzysztof Cwalina discute las sutilezas aquí: http://blogs.gotdotnet.com/kcwalina/archive/2004/08/06/210297.aspx.

+11

NameValueCollection también admite más de un valor por clave (necesario para cadenas de consulta, etc.). –

+15

No es cierto. De acuerdo con este artículo msdn sobre namevaluecollection: http://msdn.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection.aspx "Las colecciones de este tipo no conservan el orden del elemento, y no se garantiza un orden particular al enumerar la colección ". – kateroh

9

La otra ventaja de IDictionary es que no es específico de implementación a diferencia de NameValueCollection.

+0

¿qué significa 'implimentation specific'? –

+0

'NameValueCollection' es un tipo concreto. 'IDictionary' es una interfaz. Entonces, con la interfaz tiene más flexibilidad ya que puede usar cualquier clase concreta que implemente esa interfaz. – Fred

4

Estoy de acuerdo con fatcat y lomaxx (y voté por las respuestas). Añadiría que el rendimiento de los tipos de recolección debería ser la última consideración al elegir entre los tipos de colección. Use el tipo que más se ajuste a sus necesidades de uso. Si se encuentra en una sección de código de rendimiento crítico (y probablemente no lo sea), entonces la única respuesta es medir cada caso; no crea en Interweb, no cree en los números.

+0

+1 para advertencia Interweb. Es una manera de Jack Black de ser aristotélico y promover el uso del trivium. –

+0

realmente? ¿El rendimiento no es la única razón por la que existen diferentes tipos de colección? de lo contrario, solo estaríamos usando List para todo. – Spongman

2

A NameValueCollection en .NET es básicamente lo que se utiliza para QueryStrings para mantener los pares clave/valor. La mayor diferencia es cuando se agregan dos elementos con la misma clave. Con IDictionary, hay dos formas de establecer un valor. El uso del método .Add() generará un error en una clave duplicada cuando la clave ya exista. Pero simplemente establecer el elemento igual a un valor sobrescribirá el valor. Así es como IDictionary maneja claves duplicadas. Pero NameValueCollection agregará valores como este: "value1, value2, value3". Por lo tanto, el valor del elemento existente se agrega con una coma, y ​​luego se agrega el nuevo valor cada vez.

Me parece que este NameValueCollection fue creado específicamente para QueryString uso y acceso. Un QueryString como "? A = 1 & b = 2 & a = 3" en .NET dará como resultado el elemento ["a"] = "1,3". Esta diferencia de cómo se tratan las claves duplicadas es la diferencia "real", es decir, la mayor diferencia entre las dos.

I sospechoso que un NameValueCollection también no utiliza ninguna tabla hash para un rápido acceso de las teclas cuando la colección es grande ya que este acceso es más lento para las pequeñas colecciones que sin la tabla hash. No he encontrado información definitiva que indique si una NameValueCollection utiliza o no una tabla hash para acceder a las claves. I do saber que un IDictionary usa una tabla hash para que el acceso a las claves en un IDictionary con muchas teclas sea bastante rápido. Entonces, sospecho que una NameValueCollection es más rápida para colecciones pequeñas que un IDictionary. Si mi conjetura es correcta, entonces wud significa que un shift de NameValueCollection de ninguna manera se usa para grandes colecciones ya que cuanto mayor sea, masivamente se ralentiza sin una tabla hash para acceder a las claves.

Para el número de llaves en una cadena de consulta, este número es normalmente muy pequeña, así que supongo WUD la NameValueCollection hace no hashes de uso, para un mejor rendimiento.Pero si Microsoft diseñó cosas para el rendimiento y para lo que es mejor para sus usuarios, Windows será por lo que es diferente de lo que es hoy. Entonces no podemos asumir nada que 'shud be'.

Además, quiero aclarar un reclamo incorrecto por la respuesta más popular a esta pregunta. El comentario de Kateroh debajo de la respuesta incorrecta lo dice bien enuf, que no necesito agregarle nada. Pero repito el comentario de Kateroh aquí, así que tal vez más personas se darán cuenta de que la respuesta más popular es mal. Kateroh correctamente afirma:

Cuestiones relacionadas