Avoid vectored writes for small websocket messages

Motivation:
The WebSocket08FrameEncoder contains an optimization path for small messages which copies the message content into the header buffer to avoid vectored writes. However this path is in the current implementation never taken because the target buffer is preallocated only for exactly the size of the header.

Modification:
For messages below a certain treshold allocate the buffer so that the message can be directly copied. Thereby the optimized path is taken.

Result:
A speedup of about 25% for 100byte messages. Declines with bigger message sizes. I have currently set the treshold to 1kB which is a point where I could still see a few percent speedup, but we should also avoid burning too many CPU cycles.
This commit is contained in:
Matthias Einwag 2014-10-03 23:35:46 +02:00 committed by Norman Maurer
parent 2af04ea2ee
commit abb06779c8

View File

@ -81,6 +81,14 @@ public class WebSocket08FrameEncoder extends MessageToMessageEncoder<WebSocketFr
private static final byte OPCODE_PING = 0x9;
private static final byte OPCODE_PONG = 0xA;
/**
* The size treshold for gathering writes. Non-Masked messages bigger than this size will be be sent fragmented as
* a header and a content ByteBuf whereas messages smaller than the size will be merged into a single buffer and
* sent at once.<br>
* Masked messages will always be sent at once.
*/
private static final int GATHERING_WRITE_TRESHOLD = 1024;
private final boolean maskPayload;
/**
@ -140,7 +148,7 @@ public class WebSocket08FrameEncoder extends MessageToMessageEncoder<WebSocketFr
int maskLength = maskPayload ? 4 : 0;
if (length <= 125) {
int size = 2 + maskLength;
if (maskPayload) {
if (maskPayload || length <= GATHERING_WRITE_TRESHOLD) {
size += length;
}
buf = ctx.alloc().buffer(size);
@ -149,7 +157,7 @@ public class WebSocket08FrameEncoder extends MessageToMessageEncoder<WebSocketFr
buf.writeByte(b);
} else if (length <= 0xFFFF) {
int size = 4 + maskLength;
if (maskPayload) {
if (maskPayload || length <= GATHERING_WRITE_TRESHOLD) {
size += length;
}
buf = ctx.alloc().buffer(size);
@ -159,7 +167,7 @@ public class WebSocket08FrameEncoder extends MessageToMessageEncoder<WebSocketFr
buf.writeByte(length & 0xFF);
} else {
int size = 10 + maskLength;
if (maskPayload) {
if (maskPayload || length <= GATHERING_WRITE_TRESHOLD) {
size += length;
}
buf = ctx.alloc().buffer(size);