Skip to content

Conversation

@robin-aws
Copy link
Member

@robin-aws robin-aws commented Sep 10, 2025

What was changed?

Continuing from #6353, this change ensures the same optimization to avoid boxing bytes, Chars and CodePoints in sequences is also used in the concatenation optimization implemented in dafnyRuntime.dfy. In particular, it ensures the new Arrays created to hold the result are also optimized for those types. This required modifying the Sequence<T> implementation to expose a PrototypeArray() to indicate the array type at runtime. The overall solution mirrors the solution in DafnyRuntimeJava quite closely.

How has this been tested?

Existing tests. Performance improvement was measured using https://github.com/aws/aws-encryption-sdk/tree/mainline/esdk-performance-testing/benchmarks/go. On a payload of 100 MB, the peak memory usage before was 5822 MB, and after the optimization was 595 MB. The average latency also improved from 3652 ms to 2047 ms.

By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

@robin-aws robin-aws changed the title New array with prototype feat: Avoid boxing primitives in Go in sequence concatenations as well Sep 10, 2025
@robin-aws robin-aws marked this pull request as ready for review September 10, 2025 17:24
@robin-aws robin-aws enabled auto-merge (squash) September 10, 2025 17:49
Copy link
Collaborator

@RustanLeino RustanLeino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@robin-aws robin-aws merged commit 80a1382 into dafny-lang:master Sep 10, 2025
57 of 60 checks passed
@robin-aws robin-aws deleted the new-array-with-prototype branch September 10, 2025 21:30
robin-aws added a commit that referenced this pull request Oct 20, 2025
### What was changed?

There are two issues causing excessive memory usage when using Seq in
Dafny Go:
1. Dafny Go compiler uses an empty sequence whenever declaring a new
variable. It doesn't use the specific type for sequence, but rather an
`arrayStruct` which uses `interface{}` as the underlying type. While the
[Boxing Fix](#6361) addressed
the issue when converting from native Go types to dafny Go types (and
vice versa), it didn't fix the use of arrayStruct /
[EmptySeq](https://github.com/dafny-lang/DafnyRuntimeGo/blob/38e14aaf73eff74913a994ee80fd49edf5161c17/v4/dafny/dafny.go#L517)
in the compiler.

2. This issue gets compounded when using ConcatSequence for storing byte
sequences. The
[ToByteArray](https://github.com/dafny-lang/DafnyRuntimeGo/blob/38e14aaf73eff74913a994ee80fd49edf5161c17/v4/dafny/dafny.go#L710-L731)
method for concat seq delegates to ToArray which then uses a Vector to
flatten everything into arrayStruct, causing the same issue which was
fixed by the Boxing Fix. But since the ConcatSequence also has to use
ArraySequence as the final underlying type, delegating it to the
ToByteArray recursively ends up calling the optimized ToByteArrray for
ArraySequence, improving the performance from using 800MB for 50MB
sequence to ~100MB.

This PR fixes issue 2 since fixing 2 improves memory numbers AND 3x
boost in cpu efficiency / latency numbers.

NOTE: The numbers can be further optimized by optimizing the compiler to
use specific sequence instead of arrayStruct (Issue 1) but that might be
more involved changed. A PoC compiler fix shows marginal better memory
efficiency than the fix in this PR (which makes sense since recursive
call is expensive memory wise) but worse latency / CPU numbers. A full
fix might bring the CPU numbers in line as well but it's out of scope
for this PR.


---------

Co-authored-by: Shubham Chaturvedi <[email protected]>
Co-authored-by: Robin Salkeld <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants