Describe the shipped no-alloc mechanism and measured gas behaviour instead of stale figures - #35
Conversation
…stead of stale figures The title block said combineHashes writes after the free memory pointer and pays for expansion; it hashes through scratch space 0x00-0x3f and touches neither the pointer nor any memory past it. The "~70 vs ~350 gas" figures and the README's "40-80%+" / "about 40%" bands are replaced by the mechanisms that produce the saving (allocate-and-copy vs hash in place; per-keccak fixed cost vs per-word copy) and the measured shape of the fold's saving, which depends on data per element rather than element count. hashBytes is documented as identical to what Solidity emits for keccak256(bytes) rather than as a saving, and the function-call concession now states the measured overhead's size relative to the saving. Closes #25 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FvfmeRQKubdbFW1GL3kmib
|
Warning Review limit reachedNext included review available in 23 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Team Run ID: 📒 Files selected for processing (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
|
…rategy Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FvfmeRQKubdbFW1GL3kmib # Conflicts: # src/LibHashNoAlloc.sol
Closes #25
What changed
Six sentences, nothing else:
src/LibHashNoAlloc.soltitle block L39-45, L47-49, L65-67 and thehashBytessummary line L69;README.mdL188-190 and L440-442. Numbers were replaced by the mechanisms that produce them (gas figures drift with compiler settings; mechanisms do not), and each mechanism was re-measured in this clone under the CI harness before being written down.combineHasheswrites the two words to scratch0x00-0x3fand hashes there; neither0x40nor anything past it is touched, so nothing is allocated and no expansion is paid. "No alloc" =hashBytes/hashWordshash in place,combineHasheshashes through scratch. L37-38 ("Worst case ... in which") kept byte-identical; only the mechanism sentences change.internalcall, the jump + stack shuffle costs tens of gas (measured 21), well under the saving on even one or two words (85+ gas).keccak256+ stack ops;keccak256(abi.encode(foo_))allocates a 3-word buffer, copies the fields, bumps the free memory pointer, then pays the same hash. The encoding step alone (172) costs more than the whole in-place hash (68).keccak256(bytes)keccak256(data)already compiles to the samekeccak256(add(data, 0x20), mload(data));hashBytessaves nothing over it and exists for API symmetry.keccak256calls): slightly negative for a few words, most of the gas for larger inputs.keccak256call (6 perFoo) + 6 gas/word;abi.encodecopies every word + head/tail bookkeeping. Measured envelope stated in words (about the same or slightly more with empty fields; a third to nearly half less with a handful of words; about a fifth at ~1 KB; falling further).Measurements (this clone, CI harness: solc 0.8.25, optimizer 100000 runs, cancun;
gasleft()deltas, every measured result asserted equal to its counterpart so the optimizer cannot drop it)The "40-80%+" band is real but a function of data per element; the README's "about 40%" was one point (inner≈4) on that curve. Measurement sources: the campaign's
test/adv/Gas.t.solplus a lib-vs-inline / varying-innercompanion, run against this branch; not committed because gas figures are settings-dependent and the gas tests are #26's scope.QA
gasleft()deltas under the repo's ownfoundry.tomlsettings with the measured expression's result asserted equal to its counterpart; EVM gas schedule (KECCAK256= 30 + 6/word); Solidity memory layout (0x00-0x3fscratch,0x40free memory pointer,keccak256(bytes memory)lowering).Checks run locally in the CI harness:
forge fmt --check,forge test(22 passed),slither .(0 results),rainix-sol-single-contract,reuse lint— all green.🤖 Generated with Claude Code
https://claude.ai/code/session_01FvfmeRQKubdbFW1GL3kmib