ByteArrayInputStream.flush()is no-op method along withByteArrayInputStream.close(),ByteArrayOutputStream.flush()andByteArrayOutputStream.close(). So we can droptry-with-resourcesstatements as well as explicit calls toflush()/close()new String(BAOS.toByteArray(), charset)replaced with call toStreamUtils.baosToString(baos, charset)to swallowUnsupportedEncodingExceptionwhich is actually never thrown ascharsetis already available at invocation point
As of performance I've used more precise benchmark:
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g", "-XX:+UseParallelGC"})
public class ByteArrayOutputStreamBenchmark {
@Benchmark
public String toString(Data data) throws UnsupportedEncodingException {
return data.baos.toString(data.charset.name());
}
@Benchmark
public String newString(Data data) {
return new String(data.baos.toByteArray(), data.charset);
}
@Benchmark
public String toString_noCS(Data data) {
return data.baos.toString();
}
@Benchmark
public String newString_noCS(Data data) {
return new String(data.baos.toByteArray());
}
@State(Scope.Thread)
public static class Data {
@Param({"0", "10", "100", "1000"})
private int length;
private final Charset charset = Charset.defaultCharset();
private ByteArrayOutputStream baos;
@Setup
public void setup() throws IOException {
byte[] bytes = StringUtils.repeat('a', length).getBytes(charset);
baos = new ByteArrayOutputStream(length);
baos.write(bytes);
}
}
}
Which demonstrates improvement in both time and memory consumption
JDK 8
(length) Mode Score Error Units
newString 0 avgt 66.084 ± 2.121 ns/op
toString 0 avgt 44.601 ± 0.656 ns/op
newString_noCS 0 avgt 69.694 ± 1.949 ns/op
toString_noCS 0 avgt 43.758 ± 0.333 ns/op
newString 10 avgt 53.232 ± 1.569 ns/op
toString 10 avgt 45.151 ± 0.397 ns/op
newString_noCS 10 avgt 52.005 ± 0.473 ns/op
toString_noCS 10 avgt 45.657 ± 4.325 ns/op
newString 100 avgt 96.067 ± 1.466 ns/op
toString 100 avgt 77.924 ± 0.645 ns/op
newString_noCS 100 avgt 94.716 ± 3.138 ns/op
toString_noCS 100 avgt 80.460 ± 1.375 ns/op
newString 1000 avgt 667.188 ± 33.071 ns/op
toString 1000 avgt 511.302 ± 1.730 ns/op
newString_noCS 1000 avgt 624.721 ± 20.786 ns/op
toString_noCS 1000 avgt 530.833 ± 11.087 ns/op
newString:·gc.alloc.rate.norm 0 avgt 96.000 ± 0.001 B/op
toString:·gc.alloc.rate.norm 0 avgt 40.000 ± 0.001 B/op
newString_noCS:·gc.alloc.rate.norm 0 avgt 56.000 ± 0.001 B/op
toString_noCS:·gc.alloc.rate.norm 0 avgt 40.000 ± 0.001 B/op
newString:·gc.alloc.rate.norm 10 avgt 136.000 ± 0.001 B/op
toString:·gc.alloc.rate.norm 10 avgt 64.000 ± 0.001 B/op
newString_noCS:·gc.alloc.rate.norm 10 avgt 96.000 ± 0.001 B/op
toString_noCS:·gc.alloc.rate.norm 10 avgt 64.000 ± 0.001 B/op
newString:·gc.alloc.rate.norm 100 avgt 400.000 ± 0.001 B/op
toString:·gc.alloc.rate.norm 100 avgt 240.000 ± 0.001 B/op
newString_noCS:·gc.alloc.rate.norm 100 avgt 360.000 ± 0.001 B/op
toString_noCS:·gc.alloc.rate.norm 100 avgt 240.000 ± 0.001 B/op
newString:·gc.alloc.rate.norm 1000 avgt 3096.001 ± 0.001 B/op
toString:·gc.alloc.rate.norm 1000 avgt 2040.001 ± 0.001 B/op
newString_noCS:·gc.alloc.rate.norm 1000 avgt 3056.001 ± 0.001 B/op
toString_noCS:·gc.alloc.rate.norm 1000 avgt 2040.001 ± 0.001 B/op
Comment From: sbrannen
For future reference, please make sure you execute ./gradlew check prior to submitting a PR in order to avoid errors such as the following.
> Task :spring-core:checkstyleMain FAILED
[ant:checkstyle] [ERROR] /source/spring-framework/spring-core/src/main/java/org/springframework/util/StreamUtils.java:249:20: Javadoc element descriptions should not start with an uppercase letter. [SpringJavadoc]
[ant:checkstyle] [ERROR] /source/spring-framework/spring-core/src/main/java/org/springframework/util/StreamUtils.java:256:17: '}' at column 3 should be alone on a line. [RightCurly]
[ant:checkstyle] [ERROR] /source/spring-framework/spring-core/src/main/java/org/springframework/util/StreamUtils.java:256:55: Single letter catch variable (use "ex" instead). [SpringCatch]
Comment From: stsypanov
@sbrannen let me push once again ))
Comment From: sbrannen
I've already begun a local merge process.
So no need to push again.
Comment From: stsypanov
Ok, I was unaware about ./gradlew check, thanks for pointing that out!
Comment From: sbrannen
This has been merged into master in e63d1cf12df785d07867a09370b8e9d76dcc0c99 and further revised in 9e30620ac2a3dc5e3e963b637434667a50be2190.
Thanks