From 0bea8ecf5d851b108f788eec21a2c21098e04f99 Mon Sep 17 00:00:00 2001 From: vincent-grosbois Date: Tue, 7 Aug 2018 11:31:24 +0200 Subject: [PATCH] CompositeByteBuf nioBuffer doesn't always alloc (#8176) In nioBuffer(int,int) in CompositeByteBuf , we create a sub-array of nioBuffers for the components that are in range, then concatenate all the components in range into a single bigger buffer. However, if the call to nioBuffers() returned only one sub-buffer, then we are copying it to a newly-allocated buffer "merged" for no reason. Motivation: Profiler for Spark shows a lot of time spent in put() method inside nioBuffer(), while usually no copy of data is required. Modification: This change skips this last step and just returns a duplicate of the single buffer returned by the call to nioBuffers(), which will in most implementation not copy the data Result: No copy when the source is only 1 buffer --- buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java b/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java index 3d6fd215b937..85160c79a6e6 100644 --- a/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java @@ -1467,9 +1467,13 @@ public ByteBuffer nioBuffer(int index, int length) { } } - ByteBuffer merged = ByteBuffer.allocate(length).order(order()); ByteBuffer[] buffers = nioBuffers(index, length); + if (buffers.length == 1) { + return buffers[0].duplicate(); + } + + ByteBuffer merged = ByteBuffer.allocate(length).order(order()); for (ByteBuffer buf: buffers) { merged.put(buf); }