Skip to content

perf: make keccak preimage recording optional and strict - #1090

Merged
gustavo-grieco merged 1 commit into
mainfrom
perf-keccak
Sep 5, 2026
Merged

perf: make keccak preimage recording optional and strict#1090
gustavo-grieco merged 1 commit into
mainfrom
perf-keccak

Conversation

@elopez

@elopez elopez commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Description

Concrete Keccak recorded every preimage in vm.keccakPreImgs with a lazy modifying, building an unforced chain of Set inserts that retains every hashed buffer for the VM's lifetime. The set is only consumed when symbolic execution continues from the state (keccak constraints for the solver), so purely concrete users pay for nothing they use.

Gate the recording behind RuntimeConfig.recordKeccakPreImgs (default True, preserving existing behavior) and force the insert when it does happen.

Benchmark: Echidna fuzzing a real-world Foundry project (1 workers, 15k calls plus corpus replay) with this commit and the consumer setting the flag to False: GC time 2.89s -> 2.02s, bytes copied during GC -1.8 GB, mutator time -0.4s.

Checklist

  • tested locally
  • added automated tests
  • updated the docs
  • updated the changelog

Concrete Keccak recorded every preimage in vm.keccakPreImgs with a lazy
modifying, building an unforced chain of Set inserts that retains every
hashed buffer for the VM's lifetime. The set is only consumed when
symbolic execution continues from the state (keccak constraints for the
solver), so purely concrete users pay for nothing they use.

Gate the recording behind RuntimeConfig.recordKeccakPreImgs (default
True, preserving existing behavior) and force the insert when it does
happen.

Benchmark: Echidna fuzzing a real-world Foundry project (1 workers,
15k calls plus corpus replay) with this commit and the consumer setting
the flag to False: GC time 2.89s -> 2.02s, bytes copied during GC -1.8 GB,
mutator time -0.4s.
@elopez

elopez commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator Author
All benchmarks
All
  loop
    2:     OK
      25.1 μs ± 1.8 μs,       same as baseline
    4:     OK
      36.1 μs ± 3.5 μs,       same as baseline
    8:     OK
      57.9 μs ± 3.9 μs,       same as baseline
    16:    OK
      101  μs ± 7.8 μs,       same as baseline
    32:    OK
      187  μs ±  14 μs,       same as baseline
    64:    OK
      363  μs ±  36 μs,       same as baseline
    128:   OK
      689  μs ±  55 μs,       same as baseline
    256:   OK
      1.37 ms ±  70 μs,       same as baseline
    512:   OK
      2.75 ms ± 247 μs,       same as baseline
    1024:  OK
      5.45 ms ± 509 μs,       same as baseline
    2048:  OK
      10.6 ms ± 1.0 ms,       same as baseline
    4096:  OK
      21.2 ms ± 1.3 ms,       same as baseline
    8192:  OK
      42.7 ms ± 3.4 ms,       same as baseline
    16384: OK
      85.0 ms ± 3.6 ms,       same as baseline
  primes
    2:     OK
      80.7 μs ± 7.2 μs,       same as baseline
    4:     OK
      116  μs ± 8.3 μs,       same as baseline
    8:     OK
      181  μs ±  15 μs,       same as baseline
    16:    OK
      343  μs ±  16 μs,       same as baseline
    32:    OK
      724  μs ±  66 μs,       same as baseline
    64:    OK
      1.57 ms ± 142 μs,       same as baseline
    128:   OK
      3.62 ms ± 253 μs,       same as baseline
    256:   OK
      8.57 ms ± 531 μs,       same as baseline
    512:   OK
      20.5 ms ± 1.3 ms,       same as baseline
    1024:  OK
      49.7 ms ± 4.5 ms,       same as baseline
    2048:  OK
      123  ms ± 8.4 ms,       same as baseline
    4096:  OK
      307  ms ±  22 ms,       same as baseline
    8192:  OK
      767  ms ±  24 ms,       same as baseline
    16384: OK
      1.949 s ± 167 ms,       same as baseline
  hashes
    2:     OK
      33.2 μs ± 2.8 μs,       same as baseline
    4:     OK
      53.2 μs ± 5.0 μs,       same as baseline
    8:     OK
      91.4 μs ± 4.9 μs,       same as baseline
    16:    OK
      171  μs ±  17 μs,       same as baseline
    32:    OK
      322  μs ±  21 μs,       same as baseline
    64:    OK
      627  μs ±  35 μs,       same as baseline
    128:   OK
      1.24 ms ±  71 μs,       same as baseline
    256:   OK
      2.48 ms ± 181 μs,       same as baseline
    512:   OK
      4.89 ms ± 408 μs,       same as baseline
    1024:  OK
      9.78 ms ± 604 μs,       same as baseline
    2048:  OK
      19.4 ms ± 1.8 ms,       same as baseline
    4096:  OK
      39.0 ms ± 2.5 ms,       same as baseline
    8192:  OK
      77.4 ms ± 4.6 ms,       same as baseline
    16384: OK
      155  ms ± 7.8 ms,       same as baseline
  hashmem
    2:     OK
      52.5 μs ± 4.4 μs,       same as baseline
    4:     OK
      80.9 μs ± 3.8 μs,       same as baseline
    8:     OK
      138  μs ±  12 μs,       same as baseline
    16:    OK
      255  μs ±  15 μs,       same as baseline
    32:    OK
      486  μs ±  48 μs,       same as baseline
    64:    OK
      949  μs ±  79 μs,       same as baseline
    128:   OK
      1.89 ms ± 148 μs,       same as baseline
    256:   OK
      3.72 ms ± 108 μs,       same as baseline
    512:   OK
      7.51 ms ± 541 μs,       same as baseline
    1024:  OK
      15.3 ms ± 1.2 ms,       same as baseline
    2048:  OK
      30.7 ms ± 2.7 ms,       same as baseline
    4096:  OK
      62.3 ms ± 4.5 ms,       same as baseline
    8192:  OK
      128  ms ± 8.3 ms,       same as baseline
    16384: OK
      262  ms ±  23 ms,       same as baseline
  balanceTransfer
    2:     OK
      3.74 ms ± 240 μs,       same as baseline
    4:     OK
      3.79 ms ± 234 μs,       same as baseline
    8:     OK
      3.81 ms ± 241 μs,       same as baseline
    16:    OK
      3.87 ms ± 225 μs,       same as baseline
    32:    OK
      3.98 ms ± 254 μs,       same as baseline
    64:    OK
      4.23 ms ± 211 μs,       same as baseline
    128:   OK
      4.73 ms ± 454 μs,       same as baseline
    256:   OK
      5.69 ms ± 491 μs,       same as baseline
    512:   OK
      7.68 ms ± 491 μs,       same as baseline
    1024:  OK
      11.5 ms ± 863 μs,       same as baseline
    2048:  OK
      19.5 ms ± 1.9 ms,       same as baseline
    4096:  OK
      40.3 ms ± 1.6 ms,       same as baseline
    8192:  OK
      83.3 ms ± 5.4 ms,       same as baseline
    16384: OK
      158  ms ±  10 ms,       same as baseline
  funcCall
    2:     OK
      36.7 μs ± 1.9 μs,  9% less than baseline
    4:     OK
      50.5 μs ± 3.7 μs,  9% less than baseline
    8:     OK
      78.3 μs ± 7.1 μs,       same as baseline
    16:    OK
      133  μs ± 9.5 μs,       same as baseline
    32:    OK
      243  μs ±  14 μs,  8% less than baseline
    64:    OK
      465  μs ±  34 μs,  7% less than baseline
    128:   OK
      904  μs ±  53 μs,  7% less than baseline
    256:   OK
      1.79 ms ± 124 μs,  7% less than baseline
    512:   OK
      3.57 ms ± 240 μs,  7% less than baseline
    1024:  OK
      7.07 ms ± 594 μs,       same as baseline
    2048:  OK
      13.9 ms ± 892 μs,  8% less than baseline
    4096:  OK
      27.4 ms ± 1.8 ms,  8% less than baseline
    8192:  OK
      54.7 ms ± 3.4 ms,  8% less than baseline
    16384: OK
      110  ms ± 7.3 ms,  8% less than baseline
  contractCreation
    2:     OK
      62.3 μs ± 4.4 μs,  7% less than baseline
    4:     OK
      103  μs ± 4.1 μs,       same as baseline
    8:     OK
      181  μs ±  13 μs,       same as baseline
    16:    OK
      334  μs ±  24 μs,       same as baseline
    32:    OK
      659  μs ±  33 μs,       same as baseline
    64:    OK
      1.28 ms ±  73 μs,       same as baseline
    128:   OK
      2.71 ms ± 140 μs,       same as baseline
    256:   OK
      5.72 ms ± 422 μs,       same as baseline
    512:   OK
      13.9 ms ± 1.4 ms,       same as baseline
    1024:  OK
      33.0 ms ± 2.6 ms,       same as baseline
    2048:  OK
      72.0 ms ± 5.3 ms,       same as baseline
    4096:  OK
      154  ms ±  12 ms,       same as baseline
    8192:  OK
      315  ms ±  17 ms,       same as baseline
    16384: OK
      678  ms ±  50 ms,       same as baseline
  contractCreationMem
    2:     OK
      237  μs ±  11 μs,  8% less than baseline
    4:     OK
      413  μs ±  39 μs,       same as baseline
    8:     OK
      785  μs ±  75 μs,       same as baseline
    16:    OK
      1.56 ms ± 147 μs,       same as baseline
    32:    OK
      3.23 ms ± 246 μs,       same as baseline
    64:    OK
      7.36 ms ± 717 μs,       same as baseline
    128:   OK
      19.2 ms ± 1.3 ms,       same as baseline
    256:   OK
      44.2 ms ± 3.9 ms,       same as baseline
    512:   OK
      97.8 ms ± 9.4 ms,       same as baseline
    1024:  OK
      207  ms ± 7.7 ms,  4% less than baseline
    2048:  OK
      434  ms ±  36 ms,       same as baseline
    4096:  OK
      917  ms ±  38 ms,       same as baseline
    8192:  OK
      1.862 s ±  38 ms,       same as baseline
    16384: OK
      3.675 s ± 195 ms,       same as baseline
  arrayCreationMem
    2:     OK
      109  μs ± 9.1 μs,  7% less than baseline
    4:     OK
      284  μs ±  17 μs,       same as baseline
    8:     OK
      948  μs ±  86 μs,       same as baseline
    16:    OK
      3.55 ms ± 234 μs,       same as baseline
    32:    OK
      13.6 ms ± 852 μs,       same as baseline
    64:    OK
      54.2 ms ± 3.7 ms,  6% less than baseline
    128:   OK
      215  ms ±  15 ms,       same as baseline
    256:   OK
      851  ms ±  41 ms,  5% less than baseline
    512:   OK
      3.407 s ±  32 ms,  5% less than baseline
  mapStorage
    2:     OK
      49.0 μs ± 4.2 μs,       same as baseline
    4:     OK
      80.7 μs ± 5.9 μs,       same as baseline
    8:     OK
      145  μs ±  11 μs,       same as baseline
    16:    OK
      278  μs ±  27 μs,       same as baseline
    32:    OK
      533  μs ±  15 μs,  6% less than baseline
    64:    OK
      1.07 ms ±  89 μs,       same as baseline
    128:   OK
      2.13 ms ± 137 μs,       same as baseline
    256:   OK
      4.30 ms ± 303 μs,       same as baseline
    512:   OK
      8.68 ms ± 606 μs,       same as baseline
    1024:  OK
      17.8 ms ± 1.1 ms,  9% less than baseline
    2048:  OK
      36.0 ms ± 2.4 ms,  9% less than baseline
    4096:  OK
      75.1 ms ± 6.8 ms,  9% less than baseline
    8192:  OK
      151  ms ± 7.4 ms,  9% less than baseline
    16384: OK
      307  ms ±  20 ms,  9% less than baseline
  swapOperations
    2:     OK
      130  μs ± 9.7 μs,       same as baseline
    4:     OK
      149  μs ± 6.7 μs,  7% less than baseline
    8:     OK
      196  μs ±  14 μs,       same as baseline
    16:    OK
      275  μs ±  14 μs,       same as baseline
    32:    OK
      441  μs ±  28 μs,  7% less than baseline
    64:    OK
      782  μs ±  62 μs,       same as baseline
    128:   OK
      1.42 ms ± 117 μs,       same as baseline
    256:   OK
      2.72 ms ± 213 μs,       same as baseline
    512:   OK
      5.38 ms ± 529 μs,       same as baseline
    1024:  OK
      10.5 ms ± 906 μs,       same as baseline
    2048:  OK
      20.7 ms ± 1.7 ms,       same as baseline
    4096:  OK
      41.0 ms ± 3.7 ms,       same as baseline
    8192:  OK
      82.5 ms ± 6.9 ms,       same as baseline
    16384: OK
      163  ms ±  15 ms,       same as baseline

All 149 tests passed (587.45s)

@gustavo-grieco
gustavo-grieco merged commit d8a7dff into main Sep 5, 2026
8 of 9 checks passed
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.

3 participants