Pre-calculate totalSliceLength before ensureCapacity
ensureCapacity is quite expensive operation, and we want to minimize the
callsites of it. This commit pre-calculates the totalSliceLength before
allocating the sliceBuffer in ensureCapacity, so that only one
ensureCapacity is called per batch.
@@ -37,6 +37,7 @@ import io.airlift.slice.SliceOutput;
import org.openjdk.jol.info.ClassLayout;
import static com.facebook.presto.array.Arrays.ExpansionFactor.LARGE;
+import static com.facebook.presto.array.Arrays.ExpansionFactor.MEDIUM;
import static com.facebook.presto.array.Arrays.ExpansionOption.PRESERVE;
import static com.facebook.presto.array.Arrays.ensureCapacity;
import static com.facebook.presto.operator.MoreByteArrays.setBytes;
@@ -239,6 +240,14 @@ public class VariableWidthBlockEncodingBuffer
// guarded by the length check in the for loop, so the subtraction doesn't matter.
int sliceAddress = (int) rawSlice.getAddress() - ARRAY_BYTE_BASE_OFFSET;
+ int totalSliceLength = 0;
+ for (int i = positionsOffset; i < positionsOffset + batchSize; i++) {
+ int position = positions[i];
+ totalSliceLength += variableWidthBlock.getPositionOffset(position + 1) - variableWidthBlock.getPositionOffset(position);
+ }
+
+ sliceBuffer = ensureCapacity(sliceBuffer, sliceBufferIndex + totalSliceLength, estimatedSliceBufferMaxCapacity, MEDIUM, PRESERVE, bufferAllocator);
+
for (int i = positionsOffset; i < positionsOffset + batchSize; i++) {
int position = positions[i];
int beginOffset = variableWidthBlock.getPositionOffset(position);
@@ -249,8 +258,6 @@ public class VariableWidthBlockEncodingBuffer
offsetsBufferIndex = setIntUnchecked(offsetsBuffer, offsetsBufferIndex, lastOffset);
if (length > 0) {
- sliceBuffer = ensureCapacity(sliceBuffer, sliceBufferIndex + length, estimatedSliceBufferMaxCapacity, LARGE, PRESERVE, bufferAllocator);
-
// The slice address may be greater than 0. Since we are reading from the raw slice, we need to read from beginOffset + sliceAddress.
sliceBufferIndex = setBytes(sliceBuffer, sliceBufferIndex, sliceBase, beginOffset + sliceAddress, length);
}
