The GitHub Actions job "Validate and test" on pekko-http.git/main has failed.
Run started by GitHub user pjfanning (triggered by pjfanning).

Head commit for run:
a63fd46c3b30b9e093c513a91e4f16443498c1cd / PJ Fanning 
<[email protected]>
perf: hand ByteBuffers to Inflater and CRC32 in the coding stages (#1228)

Motivation:
Three places in the gzip/deflate stages copy a ByteString into a byte array only
to hand it to java.util.zip:

- DeflateDecompressorBase.Inflate.parse calls setInput with the whole remaining
  buffer on every parse round, via toArray, so every round copies it.
- GzipCompressor.updateCrc and GzipDecompressor.crc16 use toArrayUnsafe, which
  only avoids the copy for a compact ByteString and falls back to a full copy 
for
  a slice or a multi-fragment one.

ByteReader.remainingData is input.drop(off), so it is not compact once any byte
has been consumed, which is always the case by the time Inflate runs. Inflater
and Deflater have taken ByteBuffer input since Java 11 and CRC32 since Java 8,
and the build targets JDK 17.

Modification:
Pass reader.remainingData.asByteBuffer to Inflater.setInput. getRemaining 
reports
the buffer's remaining bytes, so the following reader.skip is unchanged. Feed 
the
checksums one buffer per fragment with asByteBuffers, which stays copy free even
for a multi-fragment ByteString, where the singular asByteBuffer would compact.

Result:
No array copy per inflate round, and no full size copy per gzipped entity.
Measured over a 1 MB input, 200 CRC32 updates: 221 ms via toArrayUnsafe versus
154 ms via a ByteBuffer for a sliced input, 102 ms versus 98 ms for a compact
one, so it is never slower and stops allocating a copy of everything gzipped.

Tests:
- sbt "http-tests / Test / testOnly org.apache.pekko.http.scaladsl.coding.*" - 
78 passed. CoderSpec already covers these paths well: 'works for any split in 
prefix + suffix' decodes at every possible split point, so remainingData is a 
slice at every offset, plus chunked decoding and corrupt input
- New CoderSpec case asserts the encoder produces identical output for a 
multi-fragment input and a compact one, pinning the per-fragment checksum. It 
is a regression guard, not a failing-before test, since the previous code was 
also correct
- sbt http/mimaReportBinaryIssues - clean
- scalafmt --mode diff-ref=upstream/main - clean

References:
None - found while auditing ByteString usage across the code base

Report URL: https://github.com/apache/pekko-http/actions/runs/34582040037

With regards,
GitHub Actions via GitBox


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to