Java Circular Byte Buffer, der java.nio.ByteBuffer erweitert

8

Jede Implementierung von Java Circular Byte Buffer, die ich in SO und anderswo referenziert gesehen habe, erweitert java.nio.ByteBuffer nicht, was für die Verwendung mit einem SocketChannel notwendig ist. Kennt jemand eine Open-Source-Implementierung, die ByteBuffer erweitert. Ich habe versucht, meinen eigenen Weg zu beschreiten, bin aber steckengeblieben, als ich feststellte, dass die Position und die restlichen Funktionen endgültig sind und ich diese überschreiben würde, um den Kopf anzupassen und Pufferüberlauf-Ausnahmen zu verhindern. Beim Senden von 5000 Nachrichten über einen Socket-Kanal mit jedem, der mich braucht, um Zeug an den Kopf eines linearen Puffers zu kopieren, addiert dies ungefähr 450 ms oder 90us pro Nachricht (die 10 Pakete enthält, also 9us pro Paket). Im Moment ist die einzige Methode, an die ich denken kann, jede Methode zu überschreiben und alles neu zu schreiben. Irgendwelche Ideen?

    
LINEMAN78 04.03.2011, 00:57
quelle

4 Antworten

6

Anstatt einen Ringpuffer zu erstellen, können Sie den Puffer viel größer als eine Nachricht machen. Angenommen, die maximale Nachrichtengröße beträgt N Bytes. Erstellen Sie einen Puffer, der 100 * N Bytes ist nur kompakt () der ByteBuffer, wenn weniger als N Bytes übrig sind. Dies reduziert den Kopieraufwand um den Faktor 100.

Eine weitere Optimierung besteht darin, den ByteBuffer zu komprimieren, wenn keine Daten übrig sind, da dies sehr schnell ist.

    
Peter Lawrey 04.03.2011, 07:45
quelle
5

Sie können java.nio.ByteBuffer nicht einfach so erweitern. Der C-Tor ist Paket privat. Es wird nicht funktionieren, b / c die Hauptidee ist die Übergabe der Adresse an einige C-Code. Sie können auch nichts überschreiben, da viele der Methoden endgültig sind. ByteBuffers wurden für Geschwindigkeit entwickelt und einige der Entscheidungen mögen seltsam aussehen, aber sie sind in Ordnung.

java.nio.channels.GatheringByteChannel und java.nio.channels.ScatteringByteChannel sind einen Versuch wert, obwohl sie ziemlich ein wenig von der Implementierung abhängig sind (natives C), um sie nützlich zu machen.

    
bestsss 04.03.2011 11:15
quelle
1

Wir könnten dies versuchen, da es Apache-Lizenz ist

Ссылка

    
Dean Hiller 09.04.2013 16:12
quelle
0

Ich würde die Methode ByteBuffer.wrap () nutzen. Wenn man sich schnell die Implementierung von Cisco anschaut, die Herr Dean Hiller zuvor gepostet hat, könnte man put () durch einen getWriteBuffer () ersetzen, der einen ByteBuffer zurückgibt, der den Teil in den Puffer schreibt, den er schreiben kann.

Dieselbe Logik kann für den Leseteil angewendet werden.

Es hätte den Vorteil, dass es nicht kompaktiert werden muss, was je nach der Anzahl der Byte im ByteBuffer teuer sein könnte, auf Kosten der Komplexität der Parsing-Logik: Sie könnten den ersten Teil Ihrer Nachricht für den ByteBuffer erhalten umschließt die letzte Region des zugrunde liegenden Ringpuffers. Um den zweiten Teil Ihrer Nachricht zu erhalten, ist ein weiterer Lesevorgang erforderlich, um das Bytearray am Anfang des Ringpuffers in einen anderen Bytepuffer zu bringen.

    
Pierre-Luc Bertrand 29.01.2014 17:21
quelle

Tags und Links