Commit 75a6693
Use a larger buffer size for
`DeflaterInputStream`, `GZIPInputStream`, `GZIPOutputStream`, and `InflaterInputStream`, all use an internal byte buffer of 512 bytes by default.
Whenever the wrapped stream exceeds this size, a full copy to a new buffer will occur, which will increase at increments of the same size. For example, a stream of length 2K will be copied four times. Increasing the size of the buffer we use can result in significant reductions in CPU usage (read: copies).
Examples in the repository
--------------------------
There are already two places where we increase the default size of these buffers:
- `//src/main/java/com/google/devtools/build/lib/bazel/repository/TarGzFunction.java`
- `//src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/HttpStream.java`
Prior art
---------
There is an open enhancement issue in the OpenJDK tracker on this which contains a benchmark for `InflaterOutputStream`:
> Increase the default, internal buffer size of the Streams in `java.util.zip`
> https://bugs.openjdk.org/browse/JDK-8242864
A similar change was merged in for JDK15+ in 2020:
> Improve performance of `InflaterOutputStream.write()`
> https://bugs.openjdk.org/browse/JDK-8242848
Providing a simple benchmark
----------------------------
I'm inlining a simple `jmh` benchmark and the results underneath it for one `GzipInputStream` case.
The benchmark:
```
@fork(1)
@threads(1)
@WarmUp(iterations = 2)
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class GZIPInputStreamBenchmark {
@param({"1024", "3072", "9216"})
long inputLength;
@param({"512", "1024", "4096", "8192"})
int bufferSize;
private byte[] content;
@setup(Level.Iteration)
public void setup() throws IOException {
var baos = new ByteArrayOutputStream();
// No need to set the buffer size on this as it's a one-time cost for setup and not counted in the result.
var gzip = new GZIPOutputStream(baos);
var inputBytes = generateRandomByteArrayOfLength(inputLength);
gzip.write(inputBytes);
gzip.finish();
this.content = baos.toByteArray();
}
@benchmark
@BenchmarkMode(Mode.AverageTime)
public void getGzipInputStream(Blackhole bh) throws IOException {
try (var is = new ByteArrayInputStream(this.content);
var gzip = new GZIPInputStream(is, bufferSize)) {
bh.consume(gzip.readAllBytes());
}
}
byte[] generateRandomByteArrayOfLength(long length) {
var random = new Random();
var intStream = random.ints(0, 5000).limit(length).boxed();
return intStream.collect(
ByteArrayOutputStream::new,
(baos, i) -> baos.write(i.intValue()),
(baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size())
).toByteArray();
}
}
```
The results:
```
Benchmark (bufferSize) (inputLength) Mode Cnt Score Error Units
GZIPInputStreamBenchmark.getGzipInputStream 512 1024 avgt 5 3207.217 ± 24.919 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 512 3072 avgt 5 5874.191 ± 5.827 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 512 9216 avgt 5 15567.345 ± 93.281 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 1024 1024 avgt 5 2580.566 ± 14.566 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 1024 3072 avgt 5 4154.582 ± 16.016 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 1024 9216 avgt 5 9942.521 ± 61.215 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 4096 1024 avgt 5 2150.255 ± 52.770 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 4096 3072 avgt 5 2289.185 ± 71.396 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 4096 9216 avgt 5 5656.891 ± 28.499 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 8192 1024 avgt 5 2177.427 ± 30.896 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 8192 3072 avgt 5 2517.390 ± 21.296 ns/op
GZIPInputStreamBenchmark.getGzipInputStream 8192 9216 avgt 5 5227.932 ± 55.525 ns/op
```
Co-authored-by: Kushal Pisavadia <[email protected]>
Closes #20316.
PiperOrigin-RevId: 588444920
Change-Id: I1fb47f0b08dcb8d72f3e2c43534c33d60efb87f2java.util.zip.*Stream classes1 parent 020b85e commit 75a6693
File tree
4 files changed
+23
-12
lines changed- src
- java_tools/singlejar/java/com/google/devtools/build
- singlejar
- zip
- main/java/com/google/devtools/build/lib
- analysis/actions
- rules/genquery
4 files changed
+23
-12
lines changedLines changed: 13 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
| 69 | + | |
69 | 70 | | |
70 | 71 | | |
71 | 72 | | |
| |||
440 | 441 | | |
441 | 442 | | |
442 | 443 | | |
443 | | - | |
| 444 | + | |
444 | 445 | | |
445 | 446 | | |
446 | 447 | | |
| |||
492 | 493 | | |
493 | 494 | | |
494 | 495 | | |
495 | | - | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
496 | 499 | | |
497 | 500 | | |
498 | 501 | | |
| |||
529 | 532 | | |
530 | 533 | | |
531 | 534 | | |
532 | | - | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
533 | 539 | | |
534 | 540 | | |
535 | 541 | | |
536 | 542 | | |
537 | 543 | | |
538 | | - | |
539 | | - | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
540 | 548 | | |
541 | 549 | | |
542 | 550 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
19 | 18 | | |
20 | 19 | | |
21 | 20 | | |
| |||
24 | 23 | | |
25 | 24 | | |
26 | 25 | | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| |||
Lines changed: 4 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
231 | 231 | | |
232 | 232 | | |
233 | 233 | | |
| 234 | + | |
234 | 235 | | |
235 | 236 | | |
236 | 237 | | |
| |||
252 | 253 | | |
253 | 254 | | |
254 | 255 | | |
255 | | - | |
| 256 | + | |
256 | 257 | | |
257 | 258 | | |
258 | 259 | | |
| |||
268 | 269 | | |
269 | 270 | | |
270 | 271 | | |
271 | | - | |
| 272 | + | |
272 | 273 | | |
273 | 274 | | |
274 | 275 | | |
| |||
293 | 294 | | |
294 | 295 | | |
295 | 296 | | |
296 | | - | |
| 297 | + | |
297 | 298 | | |
298 | 299 | | |
299 | 300 | | |
| |||
Lines changed: 4 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| 46 | + | |
| 47 | + | |
46 | 48 | | |
47 | 49 | | |
48 | 50 | | |
| |||
83 | 85 | | |
84 | 86 | | |
85 | 87 | | |
86 | | - | |
| 88 | + | |
87 | 89 | | |
88 | 90 | | |
89 | 91 | | |
| |||
138 | 140 | | |
139 | 141 | | |
140 | 142 | | |
141 | | - | |
| 143 | + | |
142 | 144 | | |
143 | 145 | | |
144 | 146 | | |
| |||
0 commit comments