You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@pekko.apache.org by "pjfanning (via GitHub)" <gi...@apache.org> on 2026/10/06 18:19:58 UTC

[PR] Avoid buffer copies with a non-synchronized ByteStringOutputStream [pekko-grpc]

pjfanning opened a new pull request, #907:
URL: https://github.com/apache/pekko-grpc/pull/907

   ### Motivation
   `Gzip.compress`, `Gzip.uncompress` and `ByteStringUtils.fromInputStream` buffer their output in a `ByteArrayOutputStream`. Its `toByteArray` copies the whole buffer, and each `write` is `synchronized`. This change was split out of #905, where it doesn't depend on the rest of the PR.
   
   ### Modification
   - Add `internal.ByteStringOutputStream`, copied from Apache Pekko HTTP (`http-core`, `org.apache.pekko.http.impl.util.ByteStringOutputStream`). It doesn't synchronize on writes, and `takeByteString()` hands the buffer over without copying when most of it is used. When it isn't, the data is copied into a smaller array so the large one isn't kept alive.
   - Use it in `Gzip.compress`, `Gzip.uncompress` and `ByteStringUtils.fromInputStream`. The deprecated `Gzip.uncompress(bytes)` now delegates to `uncompress(bytes, Int.MaxValue)`.
   - Add `GzipBenchmark`, which covers compress, uncompress and fromInputStream for 1 KiB, 64 KiB and 1 MiB payloads.
   
   The first three commits are cherry-picked from #905. The first is @timw's, from #862.
   
   ### Result
   One fewer full copy of the message on gzip decompression, on gzip compression of small messages, and when reading a message larger than the 32 KiB read buffer from an `InputStream`.
   
   `GzipBenchmark` (JDK 17, 3 forks, `-prof gc`), `main` → this branch:
   
   | Benchmark | Size | Throughput | Allocated per op |
   |---|---|---|---|
   | fromInputStream | 1 KiB | +0.2% | same |
   | fromInputStream | 64 KiB | +58.6% | −40.0% |
   | fromInputStream | 1 MiB | +34.5% | −33.7% |
   | uncompress | 1 KiB | +5.2% | −2.4% |
   | uncompress | 64 KiB | +6.3% | −27.8% |
   | uncompress | 1 MiB | +4.8% | −33.9% |
   | compress | 1 KiB | +2.9% | −27.1% |
   | compress | 64 KiB | +6.0% | same |
   | compress | 1 MiB | +5.3% | same |
   
   Large `compress` allocates the same as before. Its output buffer starts at the uncompressed size, and the compressed output fills less than half of it, so the data is deliberately copied into a smaller array.
   
   ### Tests
   - `sbt "runtime/testOnly org.apache.pekko.grpc.internal.*"`: 104 passed, including the new `ByteStringOutputStreamSpec`
   - `sbt +runtime/mimaReportBinaryIssues`: no issues
   - `sbt "benchmarks/Jmh/run -prof gc org.apache.pekko.grpc.GzipBenchmark"`: run on `main` and this branch (results above)
   - scalafmt run on the changed files
   
   ### References
   Refs #905, Refs #862
   
   `ByteStringOutputStream` is copied from Apache Pekko HTTP (Apache License 2.0, also an ASF project).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For additional commands, e-mail: notifications-help@pekko.apache.org


Re: [PR] Avoid buffer copies with a non-synchronized ByteStringOutputStream [pekko-grpc]

Posted by "pjfanning (via GitHub)" <gi...@apache.org>.
pjfanning merged PR #907:
URL: https://github.com/apache/pekko-grpc/pull/907


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For additional commands, e-mail: notifications-help@pekko.apache.org