13 Stimmen

Wo werden Werttypen in (C#) generischen Sammlungen gespeichert?

Es stimmt, dass generische Sammlungen für Werttypen besser funktionieren als nicht-generische Sammlungen. (z. B. List vs. ArrayList).

Aber warum ist das so, abgesehen von dem Schritt "Boxing-Unboxing"? Wo werden die Objekte vom Typ Wert gespeichert, nachdem sie der Sammlung hinzugefügt wurden? In nicht-generischen Sammlungen werden sie gepackt und auf dem Heap gespeichert, was ist bei generischen Sammlungen anders?

13voto

Reed Copsey Punkte 536986

Bei Generika, wie z. B. List<T> werden sie weiterhin auf dem Heap gespeichert. Der Unterschied ist, dass intern ein List<int> bildet ein einzelnes Array von Ganzzahlen und kann die Zahlen direkt speichern. Mit ArrayList speichern Sie am Ende ein Array mit Verweisen auf eingegrenzte Integer-Werte.

8voto

Hans Passant Punkte 894572

Das relevante Implementierungsdetail ist, dass der zugrunde liegende Speicher für eine List<T> ist ein T[]. Also für ein List<int> werden die Werte in einem int[] gespeichert. Die Ganzzahlen werden in einem zusammenhängenden Speicherbereich gespeichert, der aus dem Garbage-Collector-Heap zugewiesen wird.

Was es so schnell macht, ist nicht nur, dass die ganzen Zahlen nicht geboxt sind, sondern dass ein int[] so gut mit dem CPU-Cache funktioniert. Wenn Sie das erste Element lesen, erhalten Sie die nächsten 15 umsonst, ohne den langsamen RAM- oder sekundären Cache lesen zu müssen. Das funktioniert bei einem boxed int nicht so gut, weil er so groß ist und die zusätzliche Referenz eine schlechte Cache-Lokalität haben kann. Der Garbage Collector hilft jedoch dabei, diese Kosten durch die Verdichtung des Heaps zu reduzieren.

1voto

James Curran Punkte 98228

Eine ArrayList ist ein lokales Array mit Verweisen auf Objekte, die auf dem Heap gespeichert sind.

Eine generische Liste von Referenztypen ist ein lokales Array von Referenzen auf Objekte, die im Heap gespeichert sind.

Eine generische Liste von Werttypen ist ein lokales Array dieser Werttypen.

Es gibt zwei Bereiche des Speichers, die in den meisten Referenzen als "Stack" und "Heap" bezeichnet werden. Die meisten Leute, die diese Begriffe verwenden, haben keine Ahnung, warum. ("The Stack" mag ein Stapel sein, aber "The Heap" ist mit Sicherheit kein Heap). Ich bevorzuge die Begriffe "Over Here" und "Over There". Wenn sie in einer Box gespeichert sind, werden die Daten vom Typ Wert "Over There" gespeichert. Wenn sie in einem Array (vielleicht innerhalb einer generischen Liste) gespeichert werden, werden die wertartigen Daten "Over Here" gespeichert. "Hier drüben" ist besser.

0voto

Nikki9696 Punkte 5862

Dafür gibt es mehrere Gründe, u. a. die Zwischenspeicherung im Speicher und die Art und Weise, wie sie aufgezählt werden, um ihre Aufgaben zu erfüllen. Prüfen Sie dieser Beitrag, insbesondere die Kommentare .

0voto

TheCodeKing Punkte 18776

Die Leistungsgewinne bei Generika beziehen sich im Allgemeinen nur auf Werttypen, die mit Generika verwendet werden, im Vergleich zu Werttypen, die in nicht-generischen Äquivalenten gespeichert sind.

Das liegt daran, dass Werttypen mit Generika nicht in Objekte umgewandelt und auf dem Heap gespeichert werden müssen (Boxed). Vielmehr können sie auf dem Stack verbleiben, was leistungsfähiger ist.

http://msdn.microsoft.com/en-us/library/ms172181.aspx

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X