Skip to content

Commit

Permalink
BytesStreamOutput default size should be 2k instead of 32k
Browse files Browse the repository at this point in the history
We changed the default of BytesStreamOutput (used in various places in ES) to 32k from 1k with the assumption that most stream tend to be large. This doesn't hold for example when indexing small documents and adding them using XContentBuilder (which will have a large overhead).

Default the buffer size to 2k now, but be relatively aggressive in expanding the buffer when below 256k (double it), and just use oversize (1/8th) when larger to try and minimize garbage and buffer copies.

relates to #3624
closes #3638
  • Loading branch information
kimchy committed Sep 6, 2013
1 parent ccf098b commit 69670d3
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
Expand Up @@ -31,7 +31,9 @@
*/
public class BytesStreamOutput extends StreamOutput implements BytesStream {

public static final int DEFAULT_SIZE = 32 * 1024;
public static final int DEFAULT_SIZE = 2 * 1024;

public static final int OVERSIZE_LIMIT = 256 * 1024;

/**
* The buffer where data is stored.
Expand Down Expand Up @@ -73,7 +75,7 @@ public void seek(long position) throws IOException {
public void writeByte(byte b) throws IOException {
int newcount = count + 1;
if (newcount > buf.length) {
buf = ArrayUtil.grow(buf, newcount);
buf = grow(newcount);
}
buf[count] = b;
count = newcount;
Expand All @@ -82,7 +84,7 @@ public void writeByte(byte b) throws IOException {
public void skip(int length) {
int newcount = count + length;
if (newcount > buf.length) {
buf = ArrayUtil.grow(buf, newcount);
buf = grow(newcount);
}
count = newcount;
}
Expand All @@ -94,12 +96,20 @@ public void writeBytes(byte[] b, int offset, int length) throws IOException {
}
int newcount = count + length;
if (newcount > buf.length) {
buf = ArrayUtil.grow(buf, newcount);
buf = grow(newcount);
}
System.arraycopy(b, offset, buf, count, length);
count = newcount;
}

private byte[] grow(int newCount) {
// try and grow faster while we are small...
if (newCount < OVERSIZE_LIMIT) {
newCount = Math.max(buf.length << 1, newCount);
}
return ArrayUtil.grow(buf, newCount);
}

public void seek(int seekTo) {
count = seekTo;
}
Expand All @@ -108,6 +118,10 @@ public void reset() {
count = 0;
}

public int bufferSize() {
return buf.length;
}

@Override
public void flush() throws IOException {
// nothing to do there
Expand Down
Expand Up @@ -60,4 +60,17 @@ public void testSimpleStreams() throws Exception {
assertThat(in.readString(), equalTo("hello"));
assertThat(in.readString(), equalTo("goodbye"));
}

@Test
public void testGrowLogic() throws Exception {
BytesStreamOutput out = new BytesStreamOutput();
out.writeBytes(new byte[BytesStreamOutput.DEFAULT_SIZE - 5]);
assertThat(out.bufferSize(), equalTo(2048)); // remains the default
out.writeBytes(new byte[1 * 1024]);
assertThat(out.bufferSize(), equalTo(4608));
out.writeBytes(new byte[32 * 1024]);
assertThat(out.bufferSize(), equalTo(40320));
out.writeBytes(new byte[32 * 1024]);
assertThat(out.bufferSize(), equalTo(90720));
}
}

0 comments on commit 69670d3

Please sign in to comment.