ByteBufInputStream is always allocating a StringBuilder instance (#8347)

Motivation:

Avoid creating any StringBuilder instance if
ByteBufInputStream::readLine isn't used

Modifications:

The StringBuilder instance is lazy allocated on demand and
are added new test case branches to address the increased
complexity of ByteBufInputStream::readLine

Result:

Reduced GC activity if ByteBufInputStream::readLine isn't used
This commit is contained in:
Francesco Nigro 2018-10-11 08:56:30 +02:00 committed by Norman Maurer
parent fc28bccdf1
commit 83dc3b503e
2 changed files with 25 additions and 6 deletions

View File

@ -16,6 +16,7 @@
package io.netty.buffer;
import io.netty.util.ReferenceCounted;
import io.netty.util.internal.StringUtil;
import java.io.DataInput;
import java.io.DataInputStream;
@ -240,18 +241,23 @@ public class ByteBufInputStream extends InputStream implements DataInput {
return buffer.readInt();
}
private final StringBuilder lineBuf = new StringBuilder();
private StringBuilder lineBuf;
@Override
public String readLine() throws IOException {
lineBuf.setLength(0);
if (lineBuf != null) {
lineBuf.setLength(0);
}
boolean anyChar = false;
loop: while (true) {
if (!buffer.isReadable()) {
return lineBuf.length() > 0 ? lineBuf.toString() : null;
return toStringIfAnyChar(lineBuf, anyChar);
}
int c = buffer.readUnsignedByte();
anyChar = true;
switch (c) {
case '\n':
break loop;
@ -263,11 +269,22 @@ public class ByteBufInputStream extends InputStream implements DataInput {
break loop;
default:
if (lineBuf == null) {
lineBuf = new StringBuilder();
}
lineBuf.append((char) c);
}
}
return lineBuf.toString();
return lineBuf != null && lineBuf.length() > 0 ? lineBuf.toString() : StringUtil.EMPTY_STRING;
}
private static String toStringIfAnyChar(StringBuilder lineBuf, boolean anyChars) {
if (anyChars) {
return lineBuf != null && lineBuf.length() > 0 ? lineBuf.toString() : StringUtil.EMPTY_STRING;
} else {
return null;
}
}
@Override

View File

@ -188,11 +188,13 @@ public class ByteBufStreamTest {
String s = in.readLine();
assertNull(s);
int charCount = 5; //total chars in the string below without new line characters
byte[] abc = "a\nb\r\nc\nd\ne".getBytes(utf8);
int charCount = 7; //total chars in the string below without new line characters
byte[] abc = "\na\n\nb\r\nc\nd\ne".getBytes(utf8);
buf.writeBytes(abc);
in.mark(charCount);
assertEquals("", in.readLine());
assertEquals("a", in.readLine());
assertEquals("", in.readLine());
assertEquals("b", in.readLine());
assertEquals("c", in.readLine());
assertEquals("d", in.readLine());