Haben in der Arbeit eine wichtige Erfahrung gemacht, bei der Verwendung von ArrayLists, im speziellen die Contains-Methode kann sich sehr schnell in .net als BottleNeck erweisen! Näheres im Detail
In unserem Projekt haben wir ein zur Zeit ein BottleNeck Problem das durch die verschiedenen Art & Weisen wie es aufgerufen werden kann, entstanden ist.
Zur Desgin-Time war uns nicht bewusst, wie langsam und zu gleich wie schnell eine ArrayList sein kann. Das Problem war das es nur in bestimmten Use-Cases zu Tage kommt.
Es ging um die Prüfung ob ein bestimmtes Objekt bereits in einer Liste ist, und wenn nicht, dass es hinzugefügt wird. Es bot sich folgends Konstrukt an:
if(!objectContainer.Contains(objToAdd)){
objectContainer.Add(objToAdd);
}
ArrayLists arbeiten allerdings NICHT mit Indizies! D.h. der Vergleichsoperator jedes einzellenen Elementes wird wird aufgerufen und das Array wird durch iteriert.
Ich konnte in unserer Software in manchen Stellen parallel eine Hashtable führen, die Keys zu den Objekten verwaltet und nur prüft ob entsprechende Keys in der Hashtable sind oder nicht. Hashtables arbeiten mit Indizes und sind linear.
Wir optimierten die Datenbank, die Stored Procedures doch der Performancegewinn war im nur im Logfile ersichtlich (27 Stunden Verarbeitungszeit statt 30 - 3 Stunden sind bei 1,5 Billionen aufrufen nicht besonders viel).
Daher hab ich einen "Hilferuf" in die Newsgroup gestellt und ein paar interessante Antworten erhalten.
Ich erwäge die Emulation einer ArrayList die im Hintergrund auf eine SortedList oder auf einen Hashtable zurückgreift - Evt. hab ich aber später Zeit die komplete ArrayList zu entferen.
Wie auch der Newsgroup erfahren hab', gibts sogar ein zweites massives BottleNeck, die Add Methode kopiert das komplette Array um, falls der reservierte Speicher nicht aussreicht, also alle 4, 8, 16, 32, 64, 128, 256, 512, 1024 und so weiter. Das kann bei ArrayLists mit über 100.000 Einträgen schon mal eine zeitlang dauern. Davon abgesehen sind sie nicht typesafe!
Damit kein zu schlechtes auf den ArrayLists bleibt - Eine Hashtable ist auch nicht typesafe, ArrayLists die evt. gleich mit der richtigen Dimension initalisiert werden brauchen nicht umkopieren/umgruppieren, ArrayList.Contains Methode kann besonders für logische Vergleiche optimal genutzt werden (sofern die Equals Methode überladen wurde). Die Contains Abfrage ist zwar an sich sehr schnell, aber wenn man das ganze 1,5 Billionen mal macht könnte sie schneller sein
Für Performance-kritische Applikation empfehle ich dennoch andere Container Klassen als die der ArrayList!