Use heap buffers for Unpooled.copiedBuffer()

Related issue: #2028

Motivation:

Some copiedBuffer() methods in Unpooled allocated a direct buffer.  An
allocation of a direct buffer is an expensive operation, and thus should
be avoided for unpooled buffers.

Modifications:

- Use heap buffers in all copiedBuffer() methods

Result:

Unpooled.copiedBuffers() are less expensive now.
This commit is contained in:
Trustin Lee 2014-08-13 15:05:42 -07:00
parent c46b197c61
commit 2b5aa716ba
2 changed files with 15 additions and 8 deletions

View File

@ -340,10 +340,19 @@ public final class ByteBufUtil {
* is allocated via the {@link ByteBufAllocator}. * is allocated via the {@link ByteBufAllocator}.
*/ */
public static ByteBuf encodeString(ByteBufAllocator alloc, CharBuffer src, Charset charset) { public static ByteBuf encodeString(ByteBufAllocator alloc, CharBuffer src, Charset charset) {
return encodeString0(alloc, false, src, charset);
}
static ByteBuf encodeString0(ByteBufAllocator alloc, boolean enforceHeap, CharBuffer src, Charset charset) {
final CharsetEncoder encoder = CharsetUtil.getEncoder(charset); final CharsetEncoder encoder = CharsetUtil.getEncoder(charset);
int length = (int) ((double) src.remaining() * encoder.maxBytesPerChar()); int length = (int) ((double) src.remaining() * encoder.maxBytesPerChar());
boolean release = true; boolean release = true;
final ByteBuf dst = alloc.buffer(length); final ByteBuf dst;
if (enforceHeap) {
dst = alloc.heapBuffer(length);
} else {
dst = alloc.buffer(length);
}
try { try {
final ByteBuffer dstBuf = dst.internalNioBuffer(0, length); final ByteBuffer dstBuf = dst.internalNioBuffer(0, length);
final int pos = dstBuf.position(); final int pos = dstBuf.position();

View File

@ -412,12 +412,7 @@ public final class Unpooled {
public static ByteBuf copiedBuffer(ByteBuf buffer) { public static ByteBuf copiedBuffer(ByteBuf buffer) {
int readable = buffer.readableBytes(); int readable = buffer.readableBytes();
if (readable > 0) { if (readable > 0) {
ByteBuf copy; ByteBuf copy = buffer(readable);
if (buffer.isDirect()) {
copy = directBuffer(readable);
} else {
copy = buffer(readable);
}
copy.writeBytes(buffer, buffer.readerIndex(), readable); copy.writeBytes(buffer, buffer.readerIndex(), readable);
return copy; return copy;
} else { } else {
@ -637,6 +632,9 @@ public final class Unpooled {
* {@code 0} and the length of the encoded string respectively. * {@code 0} and the length of the encoded string respectively.
*/ */
public static ByteBuf copiedBuffer(char[] array, Charset charset) { public static ByteBuf copiedBuffer(char[] array, Charset charset) {
if (array == null) {
throw new NullPointerException("array");
}
return copiedBuffer(array, 0, array.length, charset); return copiedBuffer(array, 0, array.length, charset);
} }
@ -657,7 +655,7 @@ public final class Unpooled {
} }
private static ByteBuf copiedBuffer(CharBuffer buffer, Charset charset) { private static ByteBuf copiedBuffer(CharBuffer buffer, Charset charset) {
return ByteBufUtil.encodeString(ALLOC, buffer, charset); return ByteBufUtil.encodeString0(ALLOC, true, buffer, charset);
} }
/** /**