MessageToByteEncoder always starts with ByteBuf that use initalCapacity == 0
Motivation: MessageToByteEncoder always starts with ByteBuf that use initalCapacity == 0 when preferDirect is used. This is really wasteful in terms of performance as every first write into the buffer will cause an expand of the buffer itself. Modifications: - Change ByteBufAllocator.ioBuffer() use the same default initialCapacity as heapBuffer() and directBuffer() - Add new allocateBuffer method to MessageToByteEncoder that allow the user to do some smarter allocation based on the message that will be encoded. Result: Less expanding of buffer and more flexibilty when allocate the buffer for encoding.
This commit is contained in:
parent
9fb6fb3236
commit
35c7f66c48
@ -96,9 +96,9 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
|
|||||||
@Override
|
@Override
|
||||||
public ByteBuf ioBuffer() {
|
public ByteBuf ioBuffer() {
|
||||||
if (PlatformDependent.hasUnsafe()) {
|
if (PlatformDependent.hasUnsafe()) {
|
||||||
return directBuffer(0);
|
return directBuffer(DEFAULT_INITIAL_CAPACITY);
|
||||||
}
|
}
|
||||||
return heapBuffer(0);
|
return heapBuffer(DEFAULT_INITIAL_CAPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,7 +43,7 @@ public interface ByteBufAllocator {
|
|||||||
ByteBuf buffer(int initialCapacity, int maxCapacity);
|
ByteBuf buffer(int initialCapacity, int maxCapacity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a {@link ByteBuf} whose initial capacity is 0, preferably a direct buffer which is suitable for I/O.
|
* Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O.
|
||||||
*/
|
*/
|
||||||
ByteBuf ioBuffer();
|
ByteBuf ioBuffer();
|
||||||
|
|
||||||
|
@ -102,11 +102,7 @@ public abstract class MessageToByteEncoder<I> extends ChannelHandlerAdapter {
|
|||||||
if (acceptOutboundMessage(msg)) {
|
if (acceptOutboundMessage(msg)) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
I cast = (I) msg;
|
I cast = (I) msg;
|
||||||
if (preferDirect) {
|
buf = allocateBuffer(ctx, cast, preferDirect);
|
||||||
buf = ctx.alloc().ioBuffer();
|
|
||||||
} else {
|
|
||||||
buf = ctx.alloc().heapBuffer();
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
encode(ctx, cast, buf);
|
encode(ctx, cast, buf);
|
||||||
} finally {
|
} finally {
|
||||||
@ -134,6 +130,19 @@ public abstract class MessageToByteEncoder<I> extends ChannelHandlerAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a {@link ByteBuf} which will be used as argument of {@link #encode(ChannelHandlerContext, I, ByteBuf)}.
|
||||||
|
* Sub-classes may override this method to returna {@link ByteBuf} with a perfect matching {@code initialCapacity}.
|
||||||
|
*/
|
||||||
|
protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, @SuppressWarnings("unused") I msg,
|
||||||
|
boolean preferDirect) throws Exception {
|
||||||
|
if (preferDirect) {
|
||||||
|
return ctx.alloc().ioBuffer();
|
||||||
|
} else {
|
||||||
|
return ctx.alloc().heapBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode a message into a {@link ByteBuf}. This method will be called for each written message that can be handled
|
* Encode a message into a {@link ByteBuf}. This method will be called for each written message that can be handled
|
||||||
* by this encoder.
|
* by this encoder.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user