Reduce array allocations during CompositeByteBuf construction
Motivation: Eliminate avoidable backing array reallocations when constructing composite ByteBufs from existing buffer arrays/Iterables. This also applies to the Unpooled.wrappedBuffer(...) methods. Modifications: Ensure the initial components ComponentList is sized at least as large as the provided buffer array/Iterable in the CompositeByteBuffer constructors. In single-arg Unpooled.wrappedBuffer(...) methods, set maxNumComponents to the count of provided buffers, rather than a fixed default of 16. It seems likely that most usage of these involves wrapping a list without subsequent modification, particularly since they return a ByteBuf rather than CompositeByteBuf. If a different/larger max is required there are already the wrappedBuffer(int, ...) variants. In fact the current behaviour could be considered inconsistent - if you call Unpooled.wrappedBuffer(int, ByteBuf) with a single buffer, you might expect to subsequently be able to add buffers to it (since you specified a max related to consolidation), but it will in fact return just a slice of the provided ByteBuf. Result: Fewer and smaller allocations in some cases when using CompositeByteBufs or Unpooled.wrappedBuffer(...).
This commit is contained in:
parent
b1d4b2af1c
commit
9b95b8ee62
@ -61,7 +61,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
|
||||
this.alloc = alloc;
|
||||
this.direct = direct;
|
||||
this.maxNumComponents = maxNumComponents;
|
||||
components = newList(maxNumComponents);
|
||||
components = newList(0, maxNumComponents);
|
||||
}
|
||||
|
||||
public CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents, ByteBuf... buffers) {
|
||||
@ -82,7 +82,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
|
||||
this.alloc = alloc;
|
||||
this.direct = direct;
|
||||
this.maxNumComponents = maxNumComponents;
|
||||
components = newList(maxNumComponents);
|
||||
components = newList(len, maxNumComponents);
|
||||
|
||||
addComponents0(false, 0, buffers, offset, len);
|
||||
consolidateIfNeeded();
|
||||
@ -100,18 +100,21 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
|
||||
"maxNumComponents: " + maxNumComponents + " (expected: >= 2)");
|
||||
}
|
||||
|
||||
int len = buffers instanceof Collection ? ((Collection<ByteBuf>) buffers).size() : 0;
|
||||
|
||||
this.alloc = alloc;
|
||||
this.direct = direct;
|
||||
this.maxNumComponents = maxNumComponents;
|
||||
components = newList(maxNumComponents);
|
||||
components = newList(len, maxNumComponents);
|
||||
|
||||
addComponents0(false, 0, buffers);
|
||||
consolidateIfNeeded();
|
||||
setIndex(0, capacity());
|
||||
}
|
||||
|
||||
private static ComponentList newList(int maxNumComponents) {
|
||||
return new ComponentList(Math.min(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, maxNumComponents));
|
||||
private static ComponentList newList(int initComponents, int maxNumComponents) {
|
||||
int capacityGuess = Math.min(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, maxNumComponents);
|
||||
return new ComponentList(Math.max(initComponents, capacityGuess));
|
||||
}
|
||||
|
||||
// Special constructor used by WrappedCompositeByteBuf
|
||||
|
@ -238,7 +238,7 @@ public final class Unpooled {
|
||||
* content will be visible to the returned buffer.
|
||||
*/
|
||||
public static ByteBuf wrappedBuffer(byte[]... arrays) {
|
||||
return wrappedBuffer(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, arrays);
|
||||
return wrappedBuffer(arrays.length, arrays);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -249,7 +249,7 @@ public final class Unpooled {
|
||||
* @return The readable portion of the {@code buffers}. The caller is responsible for releasing this buffer.
|
||||
*/
|
||||
public static ByteBuf wrappedBuffer(ByteBuf... buffers) {
|
||||
return wrappedBuffer(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, buffers);
|
||||
return wrappedBuffer(buffers.length, buffers);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,7 +258,7 @@ public final class Unpooled {
|
||||
* specified buffers will be visible to the returned buffer.
|
||||
*/
|
||||
public static ByteBuf wrappedBuffer(ByteBuffer... buffers) {
|
||||
return wrappedBuffer(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, buffers);
|
||||
return wrappedBuffer(buffers.length, buffers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user