On Mon, 5 Apr 2021 08:37:15 GMT, Сергей Цыпанов <github.com+10835776+stsypa...@openjdk.org> wrote:
> Hello, > > to avoid cases detected in > [https://github.com/openjdk/jdk/pull/2992](https://github.com/openjdk/jdk/pull/2992) > I propose to modify JavaDoc of `ByteArray*Stream` to explicitly mention > redundancy of wrapping with `BufferedInputStream`. > > As of `InputStream` I think in notation `It is never correct to use the > return value of this method to allocate a buffer intended to hold all data in > this stream.` the word 'never' should be replaced with 'usually': apart from > `ByteArrayInputStream` e.g. `FileInputStream.available()` often returns the > count of remaining bytes (the only exclusion I'm aware of is the files > located under `/proc/`) and indeed this count can be used to allocate a > buffer to read all the bytes in one call. > > Consider benchmark > > > @BenchmarkMode(Mode.AverageTime) > @OutputTimeUnit(TimeUnit.NANOSECONDS) > public class ByteArrayInputStreamBenchmark { > > @Benchmark > public void read(Data data, Blackhole bh) { > int value; > var in = data.bais; > while ((value = in.read()) != -1) { > bh.consume(value); > } > } > > @Benchmark > public void readBuffered(Data data, Blackhole bh) throws IOException { > int value; > var in = new BufferedInputStream(data.bais); > while ((value = in.read()) != -1) { > bh.consume(value); > } > } > > @Benchmark > public Object readAllBytes(Data data) { > var in = data.bais; > return in.readAllBytes(); > } > > @Benchmark > public Object readAllBytesBuffered(Data data) throws IOException { > var in = data.bais; > return new BufferedInputStream(in).readAllBytes(); > } > > @State(Scope.Thread) > public static class Data { > > @Param({"8", "128", "512", "1024"}) > private int length; > > private byte[] bytes; > private ByteArrayInputStream bais; > > @Setup(Level.Iteration) > public void setUp() { > bytes = new byte[length]; > ThreadLocalRandom.current().nextBytes(bytes); > } > > @Setup(Level.Invocation) > public void setUpBais() { > bais = new ByteArrayInputStream(bytes); > } > } > } > > > giving > > > (length) Score Error > Units > read 8 55.737 ± 0.431 > ns/op > read 128 533.172 ± 1.613 > ns/op > read 512 2066.238 ± 23.989 > ns/op > read 1024 4335.570 ± 20.137 > ns/op > > readBuffered 8 521.936 ± 2.454 > ns/op > readBuffered 128 971.617 ± 100.469 > ns/op > readBuffered 512 2284.472 ± 251.390 > ns/op > readBuffered 1024 4168.598 ± 77.980 > ns/op > > readAllBytes 8 34.850 ± 0.072 > ns/op > readAllBytes 128 36.751 ± 0.133 > ns/op > readAllBytes 512 45.304 ± 0.699 > ns/op > readAllBytes 1024 61.790 ± 0.386 > ns/op > > readAllBytesBuffered 8 870.454 ± 4.406 > ns/op > readAllBytesBuffered 128 910.176 ± 32.258 > ns/op > readAllBytesBuffered 512 896.155 ± 6.005 > ns/op > readAllBytesBuffered 1024 965.596 ± 29.225 > ns/op > > read:·gc.alloc.rate.norm 8 32.006 ± 0.001 > B/op > read:·gc.alloc.rate.norm 128 32.007 ± 0.004 > B/op > read:·gc.alloc.rate.norm 512 32.010 ± 0.010 > B/op > read:·gc.alloc.rate.norm 1024 32.011 ± 0.008 > B/op > > readBuffered:·gc.alloc.rate.norm 8 8280.354 ± 0.016 > B/op > readBuffered:·gc.alloc.rate.norm 128 8240.484 ± 0.015 > B/op > readBuffered:·gc.alloc.rate.norm 512 8240.599 ± 0.056 > B/op > readBuffered:·gc.alloc.rate.norm 1024 8280.978 ± 0.024 > B/op > > readAllBytes:·gc.alloc.rate.norm 8 56.008 ± 0.001 > B/op > readAllBytes:·gc.alloc.rate.norm 128 176.017 ± 0.001 > B/op > readAllBytes:·gc.alloc.rate.norm 512 560.035 ± 0.002 > B/op > readAllBytes:·gc.alloc.rate.norm 1024 1072.057 ± 0.002 > B/op > > readAllBytesBuffered:·gc.alloc.rate.norm 8 16512.660 ± 0.026 > B/op > readAllBytesBuffered:·gc.alloc.rate.norm 128 16632.684 ± 0.008 > B/op > readAllBytesBuffered:·gc.alloc.rate.norm 512 17016.694 ± 0.017 > B/op > readAllBytesBuffered:·gc.alloc.rate.norm 1024 17528.748 ± 0.012 > B/op Hi, I create the issue https://bugs.openjdk.java.net/browse/JDK-8265039 for this PR🚀. ------------- PR: https://git.openjdk.java.net/jdk/pull/3341