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.
This commit is contained in:
Norman Maurer 2016-07-19 14:56:49 +02:00
parent fa84e86f78
commit 9151739577
2 changed files with 14 additions and 24 deletions

View File

@ -16,6 +16,7 @@
package io.netty.handler.codec.compression; package io.netty.handler.codec.compression;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.util.ByteProcessor;
import static io.netty.handler.codec.compression.Bzip2Constants.*; 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}) * 7. Huffman encode and write data - {@link #close(ByteBuf)} (through {@link Bzip2HuffmanStageEncoder})
*/ */
final class Bzip2BlockCompressor { 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. * A writer that provides bit-level writes.
*/ */
@ -197,22 +205,15 @@ final class Bzip2BlockCompressor {
/** /**
* Writes an array to the block. * 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 offset The offset within the input data to write from
* @param length The number of bytes of input data to write * @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 * @return The actual number of input bytes written. May be less than the number requested, or
* zero if the block is already full * zero if the block is already full
*/ */
int write(final byte[] data, int offset, int length) { int write(final ByteBuf buffer, int offset, int length) {
int written = 0; int index = buffer.forEachByte(offset, length, writeProcessor);
return index == -1 ? length : index - offset;
while (length-- > 0) {
if (!write(data[offset++])) {
break;
}
written++;
}
return written;
} }
/** /**

View File

@ -121,19 +121,8 @@ public class Bzip2Encoder extends MessageToByteEncoder<ByteBuf> {
return; return;
} }
Bzip2BlockCompressor blockCompressor = this.blockCompressor; Bzip2BlockCompressor blockCompressor = this.blockCompressor;
final int length = in.readableBytes() < blockCompressor.availableSize() ? final int length = Math.min(in.readableBytes(), blockCompressor.availableSize());
in.readableBytes() : blockCompressor.availableSize(); final int bytesWritten = blockCompressor.write(in, in.readerIndex(), length);
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);
in.skipBytes(bytesWritten); in.skipBytes(bytesWritten);
if (!blockCompressor.isFull()) { if (!blockCompressor.isFull()) {
if (in.isReadable()) { if (in.isReadable()) {