From 9151739577b9270ee8ae50cbda705942c927e8ff Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 19 Jul 2016 14:56:49 +0200 Subject: [PATCH] Remove unnessary memory copy when doing Bzip2 encoding Motivation: We did an unessary memory copy when doing bzip2 encoding. Modifications: Remove memory copy and just use a ByteProcessor. Result: Less memory copies and so faster. --- .../compression/Bzip2BlockCompressor.java | 23 ++++++++++--------- .../codec/compression/Bzip2Encoder.java | 15 ++---------- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2BlockCompressor.java b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2BlockCompressor.java index fd7703cda7..7b5efb277c 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2BlockCompressor.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2BlockCompressor.java @@ -16,6 +16,7 @@ package io.netty.handler.codec.compression; import io.netty.buffer.ByteBuf; +import io.netty.util.ByteProcessor; import static io.netty.handler.codec.compression.Bzip2Constants.*; @@ -32,6 +33,13 @@ import static io.netty.handler.codec.compression.Bzip2Constants.*; * 7. Huffman encode and write data - {@link #close(ByteBuf)} (through {@link Bzip2HuffmanStageEncoder}) */ final class Bzip2BlockCompressor { + private final ByteProcessor writeProcessor = new ByteProcessor() { + @Override + public boolean process(byte value) throws Exception { + return write(value); + } + }; + /** * A writer that provides bit-level writes. */ @@ -197,22 +205,15 @@ final class Bzip2BlockCompressor { /** * Writes an array to the block. - * @param data The array to write + * @param buffer The buffer to write * @param offset The offset within the input data to write from * @param length The number of bytes of input data to write * @return The actual number of input bytes written. May be less than the number requested, or * zero if the block is already full */ - int write(final byte[] data, int offset, int length) { - int written = 0; - - while (length-- > 0) { - if (!write(data[offset++])) { - break; - } - written++; - } - return written; + int write(final ByteBuf buffer, int offset, int length) { + int index = buffer.forEachByte(offset, length, writeProcessor); + return index == -1 ? length : index - offset; } /** diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Encoder.java b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Encoder.java index 678fd04151..a9dfe55c9e 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Encoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Encoder.java @@ -121,19 +121,8 @@ public class Bzip2Encoder extends MessageToByteEncoder { return; } Bzip2BlockCompressor blockCompressor = this.blockCompressor; - final int length = in.readableBytes() < blockCompressor.availableSize() ? - in.readableBytes() : blockCompressor.availableSize(); - final int offset; - final byte[] array; - if (in.hasArray()) { - array = in.array(); - offset = in.arrayOffset() + in.readerIndex(); - } else { - array = new byte[length]; - in.getBytes(in.readerIndex(), array); - offset = 0; - } - final int bytesWritten = blockCompressor.write(array, offset, length); + final int length = Math.min(in.readableBytes(), blockCompressor.availableSize()); + final int bytesWritten = blockCompressor.write(in, in.readerIndex(), length); in.skipBytes(bytesWritten); if (!blockCompressor.isFull()) { if (in.isReadable()) {