Skip to content

perf(encoding): reuse a single postorder traversal - #401

Draft
tvolk131 wants to merge 1 commit into
BlockstreamResearch:masterfrom
tvolk131:perf/single-pass-program-encoding
Draft

tvolk131 wants to merge 1 commit into
BlockstreamResearch:masterfrom
tvolk131:perf/single-pass-program-encoding

Conversation

@tvolk131

@tvolk131 tvolk131 commented Oct 25, 2026 •

Copy link
Copy Markdown

encode_program traverses the encoding DAG once to count nodes and again to encode them, repeating sharing-map and traversal work. Collect the postorder entries once, write their count, then encode those same entries. Sharing rules, node order, and encoding bytes stay the same.

This draft needs maintainer feedback on the CPU/memory tradeoff before adoption. The change retains an additional vector proportional to encoded node count.

Warmed release-mode serialization measurements on macOS ARM64 with Rust 1.99 (median of 33 paired thread-CPU samples):

  • 8 distinct leaves: 7.36 µs to 5.55 µs, 24.7% less CPU time.
  • 2,048 distinct leaves: 2.120 ms to 1.537 ms, 27.5% less CPU time.
  • One leaf reused through 48 composition levels: 14.85 µs to 8.49 µs, 42.8% less CPU time.

Peak live requested heap during serialization increased from 621,072 to 1,059,336 bytes for the 2,048-leaf fixture, and from 9,901,072 to 16,913,416 bytes for 32,768 leaves (about 71% more). Allocation tracking starts after graph construction and a warm-up, includes the output buffer, and excludes allocator metadata and allocator-internal reallocation transients; these figures are not process RSS. Outputs were byte-identical for all fixtures. These synthetic measurements do not establish application-level impact.

Validation:

  • cargo test --locked --workspace --all-features (120 library tests, 14 sys tests, 2 doctests), including existing canonical-encoding, hidden-node, sharing, witness, and disconnect cases
  • cargo test --locked -p simplicity-lang --lib --no-default-features (64 tests)
  • cargo +1.74.0 test --offline --locked -p simplicity-lang --lib --all-features (120 tests)
  • cargo fmt --all -- --check
  • cargo clippy --locked --workspace --all-targets --all-features -- --deny warnings

This is independent of the stack-suffix optimization. A combined experiment reduced serialization CPU time by 31.5%, 33.6%, and 43.7% on the three timing fixtures, with the same measured peak requested heap as this change alone.

Written by OpenAI Codex.

Written with GPT 6.1 Sol on Extra High.

@tvolk131

Copy link
Copy Markdown
Author

Draft until I finish iterating on it and hand-read & hand-test the code

Collect postorder entries once to obtain the node count and encode the same entries, avoiding repeated traversal and sharing-map work at the cost of temporary node storage.

Written by OpenAI Codex.
@tvolk131
tvolk131 force-pushed the perf/single-pass-program-encoding branch from 83442be to 61dd31f Compare October 26, 2026 04:41
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.

1 participant