2009-03-06 19 views
29

Ho uno scenario in cui posso utilizzare sia NameValueCollection o IDictionary. Ma mi piacerebbe sapere quale sarà il rendimento migliore.IDictionary <string, string> o NameValueCollection

- Utilizzando NameValueCollection

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

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

    if(sorting) 
     //sort NameValueCollection nc here 

    return nc; 
} 

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

risposta

28

Questi tipi di raccolta non sono esattamente intercambiabili: NameValueCollection permette l'accesso tramite indici interi. Se non hai bisogno di quella funzionalità, non dovresti utilizzare NameValueCollection poiché l'indicizzazione non viene "gratis".

A seconda del numero di stringhe che stai guardando, considererei Hashtable o IDictionary. Krzysztof Cwalina discute le sottigliezze qui: http://blogs.gotdotnet.com/kcwalina/archive/2004/08/06/210297.aspx.

+11

NameValueCollection supporta anche più di un valore per chiave (necessario per stringhe di query, ecc.). –

+15

Non vero. Secondo questo articolo di msdn su namevaluecollection: http://msdn.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection.aspx "Le raccolte di questo tipo non conservano l'ordinamento dell'elemento e no l'ordine particolare è garantito quando si enumera la collezione. " – kateroh

9

L'altro vantaggio di IDictionary è che non è specifico di implementazione a differenza di NameValueCollection.

+0

cosa significa "specifica sull'impianto"? –

+0

'NameValueCollection' è un tipo concreto. 'IDictionary' è un'interfaccia. Quindi con l'interfaccia si ha una maggiore flessibilità in quanto è possibile utilizzare qualsiasi classe concreta che implementa tale interfaccia. – Fred

4

Sono d'accordo con Fatcat e Lomaxx (e ho votato per entrambe le risposte). Vorrei aggiungere che le prestazioni dei tipi di raccolta dovrebbero molto probabilmente essere l'ultima considerazione quando si sceglie tra i tipi di raccolta. Usa il tipo che più si adatta alle tue esigenze di utilizzo. Se ti trovi in ​​una sezione di codice critico dal punto di vista delle prestazioni (e molto probabilmente non lo sei), l'unica risposta è misurare ogni caso: non credere all'Interweb, credi ai numeri.

+0

+1 per avviso Interweb. È un modo Jack Black per essere aristotelico e promuovere l'uso del trivio. –

+0

davvero? non è la prestazione il singolo motivo per cui esistono diversi tipi di raccolta? altrimenti useremmo semplicemente List per tutto. – Spongman

2

Un NameValueCollection in .NET è fondamentalmente ciò che viene utilizzato per QueryStrings per contenere coppie chiave/valore. La più grande differenza è quando vengono aggiunti due elementi con la stessa chiave. Con IDictionary, ci sono due modi per impostare un valore. L'utilizzo del metodo .Add() genera un errore su una chiave duplicata quando la chiave esiste già. Ma semplicemente impostando la voce uguale a un valore si sovrascriverà il valore. In questo modo IDictionary gestisce le chiavi duplicate. Ma NameValueCollection aggiungerà valori come questo: "valore1, valore2, valore3". Quindi il valore dell'elemento esistente viene aggiunto con una virgola, quindi il nuovo valore viene aggiunto ogni volta.

Mi sembra che questo NameValueCollection sia stato creato appositamente per l'utilizzo e l'accesso di QueryString. Un oggetto QueryString come "? A = 1 & b = 2 & a = 3" in .NET produrrà un risultato dell'articolo ["a"] = "1,3". Questa differenza di come vengono trattate le chiavi duplicate è la differenza "reale", cioè la più grande differenza tra i due.

I sospetto che un NameValueCollection non utilizza alcuna tabella hash per l'accesso rapido delle chiavi quando la raccolta è grande perché questo accesso è più lento per le raccolte di piccole dimensioni che senza la tabella hash. Non ho trovato informazioni definitive che indicano se un NameValueCollection fa o non usa una tabella hash per accedere alle chiavi. I do sa che un IDictionary usa una tabella hash in modo che l'accesso alle chiavi in ​​un IDictionary con molte chiavi sia abbastanza veloce. Quindi io sospetto che un NameValueCollection è più veloce per le piccole raccolte di un IDictionary. Se la mia ipotesi è corretta, vuol dire che non si usa mai uno shud NameValueCollection per le raccolte di grandi dimensioni poiché più grande è, rallenta in modo massivo senza una tabella hash per accedere alle chiavi.

Per il numero di chiavi in ​​una querystring, questo numero è normalmente molto piccolo, quindi i wud indovinare il NameValueCollection fa non uso hash, per migliorare le prestazioni.Ma se Microsoft ha progettato le cose per le prestazioni e per ciò che è meglio per i propri utenti, Windows è quindi diverso da quello attuale. Quindi non possiamo assumere nulla che 'shud essere'.

Inoltre, voglio chiarire un reclamo non corretto dalla risposta più popolare votata a questa domanda. Il commento di Kateroh al di sotto della risposta sbagliata dice che va bene, che non ho bisogno di aggiungere nulla ad esso. Ma ripeto il commento di Kateroh qui così solo forse più persone capiranno che la risposta più popolare è errata. Kateroh indica correttamente:

Problemi correlati