Effektivität von Array und ArrayList?



  • Hi,
    nur ne kurze Frage...

    Ich habe ein Objekt dass eine Vielzahl von Parametern in nahezu beliebiger Kombination und Anzahl aufnehmen soll. Nun frage ich mich ob es (vom Handling mal abgesehen) sinnvoll ist, all diese Parameter als Array zu deklarieren, oder lieber als ArrayList.

    Gibt es abgesehen von der dynamischen natur der arrayList vielleicht auch einen Leistungsunterschied?

    Generell werden bei jedem einzelnen dieser Objekte die meisten Felder null bleiben und nur ein paar werden jeweils 1-3 Werte übernehmen.

    //Parameter der Ability
            private Ort[] orte = null;
            private Property[] properties = null;
            private Category[] categories = null;
            private int[] intValues = null;
            private float[] floatValues = null;
            private string[] stringValues = null;
            private CardType[] cardTypes = null;
            private GameTime[] gameTimes = null;
            private Buff[] buffs = null;
            private AttackType[] attackTypes = null;
            private DefenseType[] defenseTypes = null;
            private Action[] actions = null;
            private CallCondition[] callConditions = null;
            private ValCondition[] valConditions = null;
            private Rights[] rights = null;
            private Ability[] abilities = null;
    


  • Welche Version von .NET verwendest Du? Die aktuelle? Dann benutz keine 'ArrayList' (nie mehr!) sondern stattdessen 'List<T>'. Dasselbe gilt auch für alle anderen Klassen aus dem Namensbereich 'System.Collections', die wurden allesamt ersetzt durch Klassen aus 'System.Collections.Generic'.

    Nun zu Deiner Frage: Ich würde in solchen Fällen (d.h. dynamisches Wachstum) *immer* eine dynamische Datenstruktur verwenden, mit anderen Worten eine 'List<T>' (oder, vor .NET 2.0 eben eine 'ArrayList'). Es *gibt* zwar Performance-Unterschiede zu einem normalen Array, die sind aber absolut zu vernachlässigen.



  • Vielen dank, dann tu ich das mal 😃



  • Ich hab dazu gerae übrigens eine Interessante Seite gefunden:
    Dustin Russel Campbell hat hier die effektivität verschiedener for-Schleifen untersucht 😉

    http://diditwith.net/2006/10/05/PerformanceOfForeachVsListForEach.aspx



  • TH3LL schrieb:

    http://diditwith.net/2006/10/05/PerformanceOfForeachVsListForEach.aspx

    Hm. Diese Resultate überraschen mich ganz extrem und ich hoffe, das das nur ein Spezialfall und nicht allgemeingültig ist, denn:

    Der Testfall „for-loop with pre-determined count“ darf *nicht* schneller sein als der Testfall „for-loop“! Und zwar ganz einfach aus dem Grund, dass Hejlsberg persönlich behauptet hat, dass der .Count-Aufruf durch den JITter herausoptimiert wird, d.h. zwischen den beiden Versionen dürfte es *keinen* Unterschied geben.

    Noch schlimmer wird es bei den anderen beiden Testfällen. Russel meinte, zwei calls müssten langsamer sein als ein callvirt und die Testergebnisse scheinen ihm recht zu geben. Das kann aber eigentlich nicht sein, denn in einer normalen foreach-Schleife dürfte eigentlich *kein einziger* call stattfinden: der JITter sollte diese Aufrufe nämlich ebenfalls inlinen. Und zwar *immer*. Der callvirt-Aufruf bei der Verwendung von ForEach + Delegate kann hingegen nicht ge-inlined werden, müsste demnach langsamer sein.

    Ich vermute, dass die Ursache für die komische Performance woanders zu suchen ist: und zwar empfiehlt Microsoft, bei IEnumerator.Current jedes Mal einen Gültigkeitstest auszuführen, der im Kontext einer foreach-Schleife natürlich total überflüssig ist. Eventuell wird dieser Test nicht herausoptimiert, und im Fall der ForEach-Methode findet er nicht statt. Dieser extreme Unterschied verwundert mich aber trotzdem.

    Zusammenfassung: Unter der Annahme, dass Optimierungen aktiviert sind, und der JITter wie erwartet seinen Job macht, würde ich mir folgende Reihenfolge bei der Laufzeit erwarten:

    „for-loop“ = „for-loop with pre-determined count“ = „foreach-loop“ < „List<int>.ForEach call“


Anmelden zum Antworten