Frage

Ein Array von ints in Java wird als ein Block von 32-Bit-Werte im Speicher abgelegt. Wie wird ein Array von Integer-Objekten gespeichert? d.

int[] vs. Integer[]

ich würde sich vorstellen, dass jedes Element in dem Ganzzahl-Array ein Verweis auf ein Integer-Objekt ist, und dass die Integer-Objekt hat Objektspeichergemeinkosten, ebenso wie jedes andere Objekt.

Ich hoffe jedoch, dass die JVM hat einige magische Klugheit unter der Haube gegeben, dass Ganze Zahlen sind unveränderlich und speichert sie wie ein Array von ints.

Ist meine Hoffnung sträflich naiv? Ist eine Integer-Array viel langsamer als ein int-Array in einer Anwendung, in jedem letzten Quäntchen Leistung zählt?

War es hilfreich?

Lösung

Nein VM weiß ich speichere einen Integer [] Array wie ein int [] Array aus den folgenden Gründen:

  1. Es sein null Integer-Objekte im Array, und Sie haben keine Bits zur Anzeige dieses in einem int-Array links. Die VM könnte speichern Sie diese 1-Bit-Informationen pro Array-Slot in einem Hiden Bit-Array though.
  2. Sie können in die Elemente eines Integer-Array synchronisieren. Das ist viel schwieriger als der erste Punkt zu überwinden, da Sie ein Monitor-Objekt für jeden Array-Slot speichern würden.
  3. Die Elemente der Integer [] kann für Identität verglichen werden. Sie könnten zum Beispiel erstellen zwei Integer-Objekte mit dem Wert 1 über neuen und speichert sie in verschiedenen Array-Slots und ihnen später abrufen und über == vergleichen. Dies muss auf false führen, so dass Sie diese Informationen irgendwo speichern würden. Oder Sie halten einen Verweis auf eine der Integer-Objekte irgendwo und verwenden diese für den Vergleich und Sie müssen sicher eine der == Vergleiche machen, ist falsch und ein wahr. Dies bedeutet, dass das gesamte Konzept der Objektidentität ist ruhig hart für den optimiert Integer-Array zu behandeln.
  4. Sie können werfen ein Integer [], um zum Beispiel Object [] und geben es an Methoden erwarten nur ein Object []. Das bedeutet, die gesamten Code, die Objekt-Handles [] muss nun die spezielle Integer [] zu handhaben kann, zu widersprechen, es langsamer und größer zu machen.

Wenn man all dies berücksichtigt, wäre es wahrscheinlich möglich sein, eine spezielle Integer [] zu machen, die im Vergleich etwas Platz spart bis zu ein naiv Umsetzung, aber die zusätzliche Komplexität wird wahrscheinlich eine Menge anderer beeinflussen Code, so dass es langsamer am Ende.

Der Aufwand der Verwendung von Integer [] anstelle von int [] kann ruhig groß in Raum und Zeit. An einem typischen 32-Bit-Integer VM wird ein Objekt 16 Byte (8 Byte für den Objektkopf, 4 für die Nutzlast und 4 Bytes für zusätzliche alignment) verbrauchen, während die ganze Zahl [] so viel Raum wie int [] verwendet. In 64-Bit-VMs (unter Verwendung von 64-Bit-Zeigern, die nicht immer der Fall ist) verbrauchen ein ganze Zahl von 24-Byte-Objekt (16 für den Header, 4 für die Nutzlast und 4 für die Ausrichtung). Zusätzlich im ganzen Zahl mit einem Schlitz [] wird 8 Byte anstelle von 4, wie in dem int [] verwenden. Dies bedeutet, dass Sie einen Overhead von erwarten können 16 bis 28 Byte pro Slot, der ein ist Faktor 4 bis 7 im Vergleich zu einfachen int Arrays.

Die Performance-Overhead kann vor allem zwei Gründe zu groß sein:

  1. Da Sie mehr Speicher verwenden, setzen Sie viel mehr Druck auf dem Speichersubsystem auf, so dass es wahrscheinlich Cache-Misses im Fall von Integer [] haben. Zum Beispiel, wenn Sie den Inhalt des int [] in linearer Weise durchqueren, wird der Cache-Speicher der meisten der Einträge bereits geholt, wenn Sie sie brauchen (da das Layout linear zu ist). Aber im Fall des Integer-Array, die Integer-Objekte selbst zufällig in dem Haufen zerstreut werden könnte, so dass es schwer für den Cache zu erraten, wo die nächsten Speicherreferenz wird zeigen.
  2. Die Garbage-Collection hat viel mehr Arbeit zu tun, verwendeten wegen der zusätzlichen Speicher und weil es zu scannen und zu jedem Integer-Objekt separat zu bewegen, während im Fall von int [] es nur ein Objekt und der Inhalt des Objekts nicht gescannt werden müssen (sie keinen Hinweis auf andere Objekte enthalten).

Um es zusammenzufassen, unter Verwendung eines int [] in leistungskritischen Arbeit wird sowohl viel schneller und Speicher effizienter als mit einem Integer-Array in der aktuellen VMs und es ist unwahrscheinlich, so viel in naher Zukunft ändern wird.

Andere Tipps

John Rose arbeitet an fixnums in der JVM, dieses Problem zu beheben.

Ich glaube, deine Hoffnung sträflich naiv. Insbesondere muss es sich mit der Frage beschäftigen, die Integer potenziell null sein kann, während int kann nicht sein. Das allein ist Grund genug, um den Objektzeiger zu speichern.

Das heißt, die eigentliche Objekt Zeiger auf eine unveränderliche int Instanz sein wird, insbesondere für eine ausgewählte Teilmenge von ganzen Zahlen.

Es wird nicht viel langsamer sein, aber weil ein Integer [] muss „Null“ als Eintrag akzeptieren und int [] nicht muß, gibt es eine gewisse Menge an Buchhaltung beteiligt sein, auch wenn Integer [] ist unterstützt durch ein int [].

Also, wenn jeder letzte Quäntchen Leistung zählt, Benutzer int []

Der Grund, dass Integer null sein kann, während int nicht kann, ist, weil Integer ein vollwertiger Java-Objekt ist, mit all dem Overhead, die folgenden beinhaltet. Es gibt Wert in dieser, da Sie schreiben

Integer foo = new Integer();
foo = null; 

was zu sagen, dass foo gut ist, einen Wert haben wird, aber es funktioniert noch nicht.

Ein weiterer Unterschied besteht darin, dass int führt keine Überlaufberechnung. Zum Beispiel

int bar = Integer.MAX_VALUE;
bar++;

wird erhöht fröhlich bar und Sie mit einer sehr negativen Zahl am Ende, das ist wahrscheinlich nicht das, was Sie in erster Linie bestimmt ist.

foo = Integer.MAX_VALUE;
foo++;

wird sich beschweren, was ich denke, wäre ein besseres Verhalten sein.

Ein letzter Punkt ist, dass Integer, ein Java-Objekt zu sein, mit sich trägt, den Raum Overhead eines Objekts. Ich denke, dass jemand anderes brauchen hier läuten, aber ich glaube, dass jedes Objekt 12 Byte für Overhead verbraucht, und dann der Raum für die Datenspeicherung selbst. Wenn Sie nach Leistung und Raum sind, dann frage ich mich, ob Integer die richtige Lösung ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top