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

Reply via email to