Wann wird Array, Buffer oder Direct Buffer verwendet?

Frage

Beim Schreiben einer Matrix-Klasse zur Verwendung mit OpenGL-Bibliotheken stellte sich die Frage, ob Java-Arrays oder eine Pufferstrategie zum Speichern der Daten verwendet werden sollen (JOGL bietet eine direkte Pufferkopie für Matrix-Operationen). Um dies zu analysieren, habe ich ein kleines Leistungstestprogramm geschrieben, das die relativen Geschwindigkeiten von Schleifen- und Massenoperationen auf Arrays im Vergleich zu Puffern im Vergleich zu direkten Puffern vergleicht.

Ich möchte meine Ergebnisse hier mit Ihnen teilen (da ich sie ziemlich interessant finde). Bitte zögern Sie nicht, Kommentare abzugeben und / oder auf Fehler hinzuweisen.
Der Code kann unter eingesehen werdenpastebin.com/is7UaiMV.

Anmerkungen

Loop-Read-Array ist implementiert alsA [i] = B [i] Andernfalls entfernt der JIT-Optimierer diesen Code vollständig. Tatsächlichvar = A [i] scheint so ziemlich dasselbe zu sein.

In dem Beispielergebnis für eine Arraygröße von 10.000 ist es sehr wahrscheinlich, dass das JIT-Optimierungsprogramm den geschleiften Arrayzugriff durch eine system.arraycopy-ähnliche Implementierung ersetzt hat.

Es gibt keinen Bulk-Get-Buffer-> Buffer, den Java implementiertA.get (B) wieB.put (A)Daher stimmen die Ergebnisse mit den Bulk-Put-Ergebnissen überein.

Fazit

In fast allen Situationen wird dringend empfohlen, die Java-internen Arrays zu verwenden. Die Put / Get-Geschwindigkeit ist nicht nur massiv schneller, die JIT kann auch den endgültigen Code viel besser optimieren.

Puffer solltennur verwendet werden, wennbeide es gilt

Sie müssen verarbeitengroße Mengen von Dateien.Diese Daten sind meistens oder immermassenweise verarbeitet.

Beachten Sie, dass ein Backened-Buffer über ein Java-Array verfügt, das den Inhalt des Puffers sichert. Es wird empfohlen, Operationen an diesem Rückpuffer auszuführen, anstatt put / get in einer Schleife auszuführen.

Direkte Puffer solltennur verwendet werden, wenn Sie sich Sorgen machenSpeichernutzung und nie auf die zugrunde liegenden Daten zugreifen. Sie sind etwas langsamer als nicht direkte Puffer, viel langsamer, wenn auf die zugrunde liegenden Daten zugegriffen wird, belegen aber weniger Speicher. Bei der Konvertierung von Nicht-Byte-Daten (z. B. Float-Arrays) in Bytes unter Verwendung eines direkten Puffers entsteht ein zusätzlicher Overhead.

Weitere Details finden Sie hier:

Warum nur ByteBuffer nützlich sind, wenn direkte Puffer verwendet werdenInterner Overhead auf NIO und was Puffer verlangsamtProbenergebnisse

Hinweis: Prozentangaben dienen nur der besseren Lesbarkeit und haben keine wirkliche Bedeutung.

Verwenden von Arrays der Größe 16 mit 10.000.000 Iterationen ...
-- Array tests: -----------------------------------------

Loop-write array:           87.29 ms  11,52%
Arrays.fill:                64.51 ms   8,51%
Loop-read array:            42.11 ms   5,56%
System.arraycopy:           47.25 ms   6,23%

-- Buffer tests: ----------------------------------------

Loop-put buffer:           603.71 ms  79,65%
Index-put buffer:          536.05 ms  70,72%
Bulk-put array->buffer:    105.43 ms  13,91%
Bulk-put buffer->buffer:    99.09 ms  13,07%

Bulk-put bufferD->buffer:   80.38 ms  10,60%
Loop-get buffer:           505.77 ms  66,73%
Index-get buffer:          562.84 ms  74,26%
Bulk-get buffer->array:    137.86 ms  18,19%

-- Direct buffer tests: ---------------------------------

Loop-put bufferD:          570.69 ms  75,29%
Index-put bufferD:         562.76 ms  74,25%
Bulk-put array->bufferD:   712.16 ms  93,96%
Bulk-put buffer->bufferD:   83.53 ms  11,02%

Bulk-put bufferD->bufferD: 118.00 ms  15,57%
Loop-get bufferD:          528.62 ms  69,74%
Index-get bufferD:         560.36 ms  73,93%
Bulk-get bufferD->array:   757.95 ms 100,00%
Verwenden von Arrays der Größe 1.000 mit 100.000 Iterationen ...
-- Array tests: -----------------------------------------

Loop-write array:           22.10 ms   6,21%
Arrays.fill:                10.37 ms   2,91%
Loop-read array:            81.12 ms  22,79%
System.arraycopy:           10.59 ms   2,97%

-- Buffer tests: ----------------------------------------

Loop-put buffer:           355.98 ms 100,00%
Index-put buffer:          353.80 ms  99,39%
Bulk-put array->buffer:     16.33 ms   4,59%
Bulk-put buffer->buffer:     5.40 ms   1,52%

Bulk-put bufferD->buffer:    4.95 ms   1,39%
Loop-get buffer:           299.95 ms  84,26%
Index-get buffer:          343.05 ms  96,37%
Bulk-get buffer->array:     15.94 ms   4,48%

-- Direct buffer tests: ---------------------------------

Loop-put bufferD:          355.11 ms  99,75%
Index-put bufferD:         348.63 ms  97,93%
Bulk-put array->bufferD:   190.86 ms  53,61%
Bulk-put buffer->bufferD:    5.60 ms   1,57%

Bulk-put bufferD->bufferD:   7.73 ms   2,17%
Loop-get bufferD:          344.10 ms  96,66%
Index-get bufferD:         333.03 ms  93,55%
Bulk-get bufferD->array:   190.12 ms  53,41%
Verwenden von Arrays der Größe 10.000 mit 100.000 Iterationen ...
-- Array tests: -----------------------------------------

Loop-write array:          156.02 ms   4,37%
Arrays.fill:               109.06 ms   3,06%
Loop-read array:           300.45 ms   8,42%
System.arraycopy:          147.36 ms   4,13%

-- Buffer tests: ----------------------------------------

Loop-put buffer:          3385.94 ms  94,89%
Index-put buffer:         3568.43 ms 100,00%
Bulk-put array->buffer:    159.40 ms   4,47%
Bulk-put buffer->buffer:     5.31 ms   0,15%

Bulk-put bufferD->buffer:    6.61 ms   0,19%
Loop-get buffer:          2907.21 ms  81,47%
Index-get buffer:         3413.56 ms  95,66%
Bulk-get buffer->array:    177.31 ms   4,97%

-- Direct buffer tests: ---------------------------------

Loop-put bufferD:         3319.25 ms  93,02%
Index-put bufferD:        3538.16 ms  99,15%
Bulk-put array->bufferD:  1849.45 ms  51,83%
Bulk-put buffer->bufferD:    5.60 ms   0,16%

Bulk-put bufferD->bufferD:   7.63 ms   0,21%
Loop-get bufferD:         3227.26 ms  90,44%
Index-get bufferD:        3413.94 ms  95,67%
Bulk-get bufferD->array:  1848.24 ms  51,79%

Antworten auf die Frage(2)

Ihre Antwort auf die Frage