object[] oder List<object>
-
moin moin
gibt es da eine regel wann man ein normales array verwendet oder wann eine generische liste ?
in meinem programm arbeite ich hautsaechlich mit der liste, allein schon aus dem grund das ich fast nie weiss wieviel objekte rein sollen
nun benutzt ich auch eine com schnitstelle welches ein array haben moechte
da mach ich dann einfach list.ToArray() - denk das passt eigentlichwie sieht das mit der performance aus?
bei einer anzahl von sagen wir mal 130.000 objekten {jedes objekt beinhaltet zwei DateTime, 2 bool, und 13 strings
ist da object[] oder List<object> performanter?oder wie ist das wenn ich zb informationen bekomm welche sich spaeter aber nicht mehr aendern - macht es sinn diese in einem array oder in einer List<> zu halten?
-
Hallo,
mit dem
allein schon aus dem grund das ich fast nie weiss wieviel objekte rein sollen
hast du ja schon ein wichtiges Kriterium genannt, welches schonmal für List<T> spricht.
Das heißt aber noch lange nicht dass List<T> die optimale Lösung ist. Es kommt stark drauf an was du weiter machst mit den Listen. Musst du zwischendrin ein neues Element in die Liste einfügen ist das für die List<T> katastrophal bei 130000 Elementen weil alle nach dem eingefügten Element umkopiert werden müssen. Intern verwendet die List<T> ja auch nur ein Array das an die erforderliche Größe angepasst werden muss und das heißt bei einigen Aktionen wie Elemente einfügen halt umkopierten ohne Ende. Da wäre eine LinkedList<T> besser. Die erlaubt es sehr schnell Elemente zwischendrin einzufügen ohne dass umkopiert werden muss, hat aber ihrerseits nen kräftigen Nachteil wenn du auf Elemente der Liste nichtsequenziell zugreifen musst. Sprich du suchst mit Find irgend ein bestimmtes Objekt in der Liste, dann muss er vom Listenstart alle Elemente bis zum gesuchten durchgehen, bei 130000 Elementen nicht optimal wenn du z.B. das 129999 suchstDeshalb musst du schaun was für Operationen du noch auf der Liste durchführst und danach die passende wählen. In der MSDN Lib ist zu jeder Funktion angegeben was für ne Laufzeit die in O Notation haben. Bei der Frage ob Array oder List<T> eindeutig List<T> da sie ja auch durch nen Array implementiert ist und beide sich somit nicht viel nehmen.
-
verschwendete energie. der sympathische junge filtert unregs (siehe seine profi-sig), wahrscheinlich weil er kommunikationsbehindert ist und das seiner profilneurose gut tut.
-
Prinzipiell sollte man List<T> bevorzugen (bzw. sogar ICollection<T>), wie auch schon erwähnt. Performanz-technisch macht sich das nicht wirklich bemerkbar, obwohl natürlich ein object[] immer etwas performanter ist (da ja kein overhead wie bei List<T> nötig ist)*.
Was natürlich richtig ist, ist das schon angesprochene Umkopieren, was dir allerdings auch bei einem puren Array nicht erspart bleibt, wenn er zu klein ist. Du kannst ja aber auch bei einer Liste eine initiale Größe angeben, und wenn du diese groß genug machst, dann passt das. Und du musst dich trotzdem nicht manuell um das Umkopieren kümmern, falls es doch mal nicht ausreichen sollte (<-> object[]).*: Es gibt aber Ausnahmen: Wenn du z.B. Werte-Typen speichern willst (primitive Datentypen, Structs), dann ist sogar auch aus Performanzgründen ganz klar die List<T> zu bevorzugen. Grund: Du sparst dir das (aufwändige) autoboxing-unboxing.
-
Na, es gibt auch andere die mitlesen und sich das gepostete wissen aneignen. Wenns der Op nicht haben will ... es gibt viele andere die sich darüber freuen
Wenn einem List<T> zur Verfügung steht, kann man auch T[] verwenden. object[] mit List<T> zu vergleichen ist ein wenig das Birnen und Äpfel spiel.
-
ah, danke nep - die auskunft ist gut - genau sowas wollte ich wissen {=
-
Äh.
Schulligung, aber tut List<T> nicht genauso boxen wenn T ein value type ist wie es object[] tun würde?
Würde mich jetzt grad wundern wenn das nicht so wäre.
-
Nein List<T> tut dies nicht (hab jetzt aber grad keine Quelle, bin mir aber ziemlich sicher).
ArrayList hingegen schon, da das ja auch ohne Generics arbeitet.
-
@hustbär
Gegenfrage
Boxt ein int[] genauso wie ein object[] ?
-
@Knuddlbaer:
nein, ein int[] boxt nicht.List<T> ist allerdings kein C++ Template sondern ein Generic, und ich kenne mich mit Generics in C# nicht gut genug aus um nun sagen zu können ob List<int> boxt oder nicht. Ich weiss inetwa wie Generics in Java funktionieren, dort werden im Prinzip nur automatisierte Casts reincompiliert. Wenn ich dasselbe für C# annehme dann würde das bedeuten dass List<int> sehrwohl boxt. Da ich es aber für C# nicht wirklich weiss meine Frage.
-
hustbaer schrieb:
Wenn ich dasselbe für C# annehme dann würde das bedeuten dass List<int> sehrwohl boxt. Da ich es aber für C# nicht wirklich weiss meine Frage.
Nope. in C# wird clever geboxt. alle reference types teilen sich eine generics implementierung wie in java, mit casts und so. und jeder native typ bekommt wie in c++ eine eigene implementierung.
-
Mit .Net ist es problemlos möglich Code zur Laufzeit zu generieren. Deswegen können zur Laufzeit neue spezialisierte/optimierte Versionen erzeugt werden.
-
Ist die Spezialisierung eigentlich ein interner Trick oder kann man das auch "extern" - im eigenen Code erreichen ?
-
@Helium
In Java ist es auch problemlos möglich zur Laufzeit Code zu erzeugen. Es wird nur im Zusammenhang mit Java-Generics nicht wirklich gemacht.@Shade Of Mine:
Mit "native type" meinst du jetzt auch value types (Rectangle etc.), oder? Die sind ja nicht "native", ganz egal wie man "native" nun auslegt (built-in vs. native-code).
-
hustbaer schrieb:
Mit "native type" meinst du jetzt auch value types (Rectangle etc.), oder? Die sind ja nicht "native", ganz egal wie man "native" nun auslegt (built-in vs. native-code).
sorry, haette "value type" schreiben muessen. wenn rectangle ein value type und kein reference type (dh von object abgeleitet ist), dann wird automatisch eine neue template instanz erstellt.
sprich: es gibt bei generics kein autoboxing. denn entweder ist es ein reference type, dann ist der cast nach object gratis oder es ist kein reference type, dann gibts code duplication (wien in c++).
-
hustbaer schrieb:
@Helium
In Java ist es auch problemlos möglich zur Laufzeit Code zu erzeugen. Es wird nur im Zusammenhang mit Java-Generics nicht wirklich gemacht.Das war bezogen auf den vergleich mit C++. Java verwirft die Typinformationen ja im gegensatz zu .Net komplett.
-
nep schrieb:
*: Es gibt aber Ausnahmen: Wenn du z.B. Werte-Typen speichern willst (primitive Datentypen, Structs), dann ist sogar auch aus Performanzgründen ganz klar die List<T> zu bevorzugen. Grund: Du sparst dir das (aufwändige) autoboxing-unboxing.
Das ist hier aber total irrelevant (und alles, was danach kommt, auch), denn es ging nicht um 'List<T>' vs. 'object[]' (das wäre ja auch idiotisch) sondern um 'List<object>' vs. 'object[]' und da besteht absolut kein Unterschied.