Che le performance di Hashtable/Dictionary sulla ricerca di item sia superiore è cosa stranota e messa in grande evidenza su MSDN.
Spesso però sui newsgroup leggo di persone che non usano il contenitore giusto e quindi ho deciso di mettere giù qualche numero per le operazioni più frequenti: Add e Contains. La prova è molto spartana ed è giusto per vedere l'ordine di grandezza.
Hashset<> è una nuova classe del Framework 3.5 studiata per Linq e mediamente più veloce del Dictionary.
In tutto questo la Hashtable è comunque vincente e il perché è semplice: Hashtable è thread-safe per multiple-reader e un writer. In applicazioni multithreading più di una volta l'ho usata per questo motivo e consente di evitare totalmente una montagna di lock. Se esiste la possibilità di avere più di un writer, è sufficiente mettere i lock solo sulle operazioni di scrittura e questo semplifica drasticamente il codice.
List<> è comunque una scelta valida per l'uso più tipico delle collection, l'accesso indicizzato. Non è quindi per nulla bocciata.
Una delle prossime modifiche alla mia RafCollection sarà proprio quella di costruire gli indici con dei Dictionary da usarsi con la AddIndex/RemoveIndex di IBindingList.
1 Milione di Add:
1 Milione di Add + 1 Milione di Contains su un elemento non in lista
Le Contains su List<T> sono così lente che ho dovuto interrompere l'elaborazione dopo diverse decine di minuti.
Adesso pensiamo di aggiungere al nostro business layer una Hashtable o Dictionary condiviso tra tutti gli utenti che mantenga in memoria gli indici dei dati delle tabelle più critiche sul DB. Voi mi direte che sto duplicando il lavoro che fa già egregiamente il DB (ed è vero), ma io rispondo che in certi casi può alleggerire molto significativamente il carico, permettendo forte scalabilità. Se teniamo conto che la Hashtable può essere presente su tutti gli application server mentre di DB ce n'è uno solo ...