DynamicByteBuffer

Status
Nicht offen für weitere Antworten.

eliot

Bekanntes Mitglied
Gibt's kein fertigen DynamicByteBuffer?
Ich bin irgendwie gerade verwirrt.

Hier meine Lösung:

Java:
public class DynamicByteBuffer {

    private LinkedList<byte[]> bytes;
    private int length;

    public DynamicByteBuffer() {
        bytes = new LinkedList<byte[]>();
        length = 0;
    }

    public void putByte(byte b) {
        byte[] byteArr = {b};
        bytes.add(byteArr);
        length++;
    }

    public void putByte(byte[] b) {
        bytes.add(b);
        length += b.length;
    }

    public byte[] toByteArray() {
        ByteBuffer buffer = ByteBuffer.allocate(length);
        for (byte[] b : bytes) {
            buffer.put(b);
        }
        return buffer.array();
    }

    public int length() {
        return length;
    }

    public int size() {
        return bytes.size();
    }
}

Gibt's sowas nicht in der API

regards
eliot
 

eliot

Bekanntes Mitglied
Man bin ich doof,

der java.io.ByteArrayOutputStream macht genau das gewünschte.
Hatte ihn auch schon einmal verwendet und wieder verdrängt.

Gnarf, ich brauch Urlaub, ...
 
T

tuxedo

Gast
Ja, schon. Nur wenn du das letzte bisschen Performance rauskitzeln willst solltest du ByteBuffer statt byte[] (nix anderes verwendet der ByteArrayOutputStream intern) verwenden.

Aber wenns nicht so extrem drauf ankommt geht auch das :)
 

eliot

Bekanntes Mitglied
Ja, schon. Nur wenn du das letzte bisschen Performance rauskitzeln willst solltest du ByteBuffer statt byte[] (nix anderes verwendet der ByteArrayOutputStream intern) verwenden.

Aber wenns nicht so extrem drauf ankommt geht auch das :)

ByteBuffer statt byte[]?

Was meinst du damit?
Ich nutze ByteArrayOutputStream.
Der obere Code wird nicht mehr verwendet.
regards
eliot
 
T

tuxedo

Gast
ByteBuffer ist eine Klasse aus den Java NIO Packages und ist so mancher Hinsicht performanter als das "primitive" byte und die Arrays daraus.

Ein Blick in die JavaDoc schadet da nicht.
 

eliot

Bekanntes Mitglied
ByteBuffer ist eine Klasse aus den Java NIO Packages und ist so mancher Hinsicht performanter als das "primitive" byte und die Arrays daraus.

Ein Blick in die JavaDoc schadet da nicht.

ByteBuffer scheint aber nicht dynamisch zu sein,
so dass ich es is in diesem Fall nicht nutzen kann
(es sei denn mit dem oberen Code, ob dieser dann aber schneller ist als
direkt ein ByteArrayOutputStream, lass ich mal dahingestellt).

Hier mal ein Performance Test:

Java:
public class TestByteBuffer {
    
    public static void main(String[] args) throws IOException{
        final ByteBuffer buffer = ByteBuffer.allocateDirect(10000000);
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        final byte[] b={1,2,3,4,54,7,7,4,6,7};
        Date date;
        Date end;
        date=new Date();
        for(int i=0;i<1000000;i++){
            buffer.put(b);
        }
        end=new Date();
        System.out.println(end.getTime()-date.getTime());
        
        date=new Date();
        for(int i=0;i<1000000;i++){
            out.write(b);
        }
        end=new Date();
        System.out.println(end.getTime()-date.getTime());        
    }

}

Ergebnis: ByteArrayOutputStream ist schneller als ByteBuffer

Komisch?


regards
eliot
 
Zuletzt bearbeitet:
T

tuxedo

Gast
Hab nie behauptet dass ByteBuffer dynamisch wäre. IoBuffer aus Apache MINA - Index baut auf ByteBuffer auf und ist dynamisch.

Dein Benchmark ist leider in keiner Weise repräsentativ. Exakt dein Code liefert bei mit meist bei beiden 0ms. Ab und zu hab ich mal hier 16ms, mal da 16ms. Aber sonst sind sie gleich.

Mal davon abgesehen dass Mini-Benchmarks dieser Sorte seeeehr mit Vorsicht zu genießen sind, hast du nur einen Teil des ByteBuffers getestet. Nämlich die nativen ByteBuffer (allocateDirect). Es gibt auch noch einen anderen Zweig (allocate).

Ganz zu schweigen davon, dass das allokieren ja hauptsächlich den Unterschied zwischen byte[] und ByteBuffer ausmacht.

Auch hatte ich geschrieben "in so mancher Hinsicht". Nicht "in allen Fällen".

Die meisten werden performancetechnisch mit byte[], bzw. mit dem Wrapper ByteArrayOutputStream hinsichtlich der Performance befriedigt sein.

Fazit: Wollte nur erwähnen dass ByteBuffer notwendig wird wenn es um wirkliche Performance geht (Beispiel Serveranwendung mit 5000 Clients oder so...).

- Alex
 

eliot

Bekanntes Mitglied
Dann hast du einen schnelleren Rechner als ich
(bei mir sind >100ms und <100ms) ;)

In meinem Fall reicht dann der ByteArrayOutputStream, da nicht sonderlich viel Bytes benötigt werden.

regards
eliot
 
T

tuxedo

Gast
Dann hab ich entweder ne Mördermaschine, oder du ne Ente :)

Ist ein "normaler" Office-PC, DualCore 2,13Ghz. Wobei der "Dualcore" da mit diesem einen Thread wohl nicht den Ausschlag gibt.

- Alex
 

Marco13

Top Contributor
Der Hauptvorteil des ByteBuffers ist IMHO die Kombination aus allocateDirect und GetDirectBufferAddress.... Wobei ich zugegebenermaßen SEHR irritiert war, als ich eben mal in dem Minitest oben das "allocateDirect" in "allocate" geändert habe :shock:
 

eliot

Bekanntes Mitglied
Der Hauptvorteil des ByteBuffers ist IMHO die Kombination aus allocateDirect und GetDirectBufferAddress.... Wobei ich zugegebenermaßen SEHR irritiert war, als ich eben mal in dem Minitest oben das "allocateDirect" in "allocate" geändert habe :shock:

Oh, ja, das irritiert mich auch.
Dies ist weit schneller als allocateDirect.
???
 
T

tuxedo

Gast
Na mich wundert das nicht. Bei allocateDirect wird - AFAIK - das OS bemüht Speicher für den Buffer bereit zu stellen.

allocate läuft irgendwie (habs schonmal gelesen und gewusst, aber mir ist es wieder entfallen) innerhalb der JVM ab und allokiert da den speicher, und ist deshalb schneller.

die "direct" Buffers nimmt man für gewöhnlich wenn man viel mit wenigen Buffern macht. Da fällt das "langsamere" allokieren nicht ins Gewicht.

Brauch man häufig neue Buffer nimmt man die "normalen" (ohne "direct").

Genaueres müsste ich daheim erst wieder in meinem Java NIO Buch nachschlagen. Wenn interesse besteht schau ich mal nach...

- Alex
 
Zuletzt bearbeitet von einem Moderator:

eliot

Bekanntes Mitglied
Na mich wundert das nicht. Bei allocateDirect wird - AFAIK - das OS bemüht Speicher für den Buffer bereit zu stellen.

allocate läuft irgendwie (habs schonmal gelesen und gewusst, aber mir ist es wieder entfallen) innerhalb der JVM ab und allokiert da den speicher, und ist deshalb schneller.

die "direct" Buffers nimmt man für gewöhnlich wenn man viel mit wenigen Buffern macht. Da fällt das "langsamere" allokieren nicht ins Gewicht.

Brauch man häufig neue Buffer nimmt man die "normalen" (ohne "direct").

Genaueres müsste ich daheim erst wieder in meinem Java NIO Buch nachschlagen. Wenn interesse besteht schau ich mal nach...

- Alex


Ah, ok,
das wäre toll, wenn du das nachschlagen könntest!
Es gibt eine Buch allein zu den Packages von java.nio.*?

regards
eliot
 
T

tuxedo

Gast
Jepp. Da steckt ja noch mehr drin wie nur die Buffer. Da sind auch die Netwerkpackages für Acceptor und Selector (non blocking io) drin, die RegEx Klassen und und und.

Hab nochmal schnell gegoogelt:

Also "direct" allokiert den Speicher außerhalb der JVM, was das OS zum allokieren hinzu zieht. Dadurch kann man mehr Speicher allokieren als die JVM zulässt (wenn ich das richtig verstanden hab).

"ohne direct" wird der Speicher nativ im Heap der JVM allokiert, was etwas schneller geht, da der Speicher für die JVM ja bereits vom OS reserviert wurde (so in etwa). Allerding ist das Limit dann vom JVM MaxHeap bestimmt.

Aber ich schau nochmal ins Buch wenn ich dazu komme.

- Alex
 

eliot

Bekanntes Mitglied
Danke für deine Mühe!
Das erklärt warum das allokieren langsamer ist.
Ist aber ein nettes Feature, wenn man wirklich viel Ram benötigt.

regards
eliot
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben