On Thu, 8 Dec 2022 16:33:06 GMT, Daniel Jeliński <djelin...@openjdk.org> wrote:
> This patch modifies `CipherInputStream` to avoid pointless memory allocations > when decrypting data using AEAD ciphers. > > `Cipher.update` on AEAD decryption does not output any data; instead, all > data is buffered and returned in one shot from `doFinal` call. On the other > hand, the value returned by `getOutputSize` increases after every `update` > call, which triggers multiple allocations in the existing implementation. > > This patch addresses the issue by calling the `update` overload that returns > the output buffer until one of the `update` calls returns some data. When > that happens, we know that the cipher does not buffer everything until > `doFinal`, and revert to original behavior. > > As long as `doUpdate` returns no data, the new implementation doesn't > allocate any memory. As a result, for AEAD ciphers it will only allocate once > in the `doFinal` invocation. > > There's a similar issue in CipherOutputStream that manifests when doing many > small writes; I'll file a separate bug for that. > > The PR adds a new benchmark for AES/GCM encryption and decryption using > CipherInputStream. That benchmark shows a nice improvement on decryption and > comparable results on encryption. > > Benchmark results before: > > Benchmark (dataSize) (keyLength) (provider) Mode > Cnt Score Error Units > AESGCMCipherInputStream.decrypt 16384 128 thrpt > 40 24590,604 ± 1169,075 ops/s > AESGCMCipherInputStream.decrypt 1048576 128 thrpt > 40 19,159 ± 0,219 ops/s > AESGCMCipherInputStream.encrypt 16384 128 thrpt > 40 127135,615 ± 2322,957 ops/s > AESGCMCipherInputStream.encrypt 1048576 128 thrpt > 40 2138,727 ± 16,400 ops/s > > > After: > > Benchmark (dataSize) (keyLength) (provider) Mode > Cnt Score Error Units > AESGCMCipherInputStream.decrypt 16384 128 thrpt > 40 43419,355 ± 3265,238 ops/s > AESGCMCipherInputStream.decrypt 1048576 128 thrpt > 40 789,463 ± 89,384 ops/s > AESGCMCipherInputStream.encrypt 16384 128 thrpt > 40 123014,294 ± 3302,102 ops/s > AESGCMCipherInputStream.encrypt 1048576 128 thrpt > 40 2007,224 ± 88,347 ops/s Change looks good to me ------------- Marked as reviewed by ascarpino (Reviewer). PR: https://git.openjdk.org/jdk/pull/11597