Skip to content

Re-cost indexByteString and add cost model visualization#7700

Open
Unisay wants to merge 3 commits intomasterfrom
yura/cost-model-viz-indexbytestring
Open

Re-cost indexByteString and add cost model visualization#7700
Unisay wants to merge 3 commits intomasterfrom
yura/cost-model-viz-indexbytestring

Conversation

@Unisay
Copy link
Copy Markdown
Contributor

@Unisay Unisay commented Apr 1, 2026

Summary

  • Re-ran costing benchmarks for IndexByteString on plutus-bench after the denotation change in Remove double range check in indexByteString #7699
  • Updated CPU cost parameters in builtinCostModel A/B/C (13,169 -> 183,300 picoseconds)
  • Added interactive visualization page for IndexByteString to the cost-models site
  • Updated navigation across all existing cost-model pages

Relates to #7469

Context

PR #7699 switched indexByteString from a manual bounds check + BS.index (double check) to BS.indexMaybe (single check). I verified via GHC Core dump that the intermediate Maybe compiles away entirely, and ran benchmarks on both old and new code to attribute the parameter change. See the PR comment for full benchmark results.

Add interactive visualization for the IndexByteString builtin function
to the cost-models site. This provides a visual baseline of the current
constant-cost model (13169 picoseconds CPU) before the denotation change
in #7699 that removes the redundant double bounds check.

Relates to #7469
@Unisay Unisay added the No Changelog Required Add this to skip the Changelog Check label Apr 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

PR Preview Action v1.6.3

🚀 View preview at
https://IntersectMBO.github.io/plutus/pr-preview/cost-models/pr-7700/

Built to branch gh-pages at 2026-04-02 13:59 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@Unisay
Copy link
Copy Markdown
Contributor Author

Unisay commented Apr 2, 2026

indexByteString denotation change: benchmark results

What changed

PR #7699 simplified the indexByteString builtin denotation. The old code did a manual bounds check and then called BS.index, which checked bounds again internally. The new code uses BS.indexMaybe instead, doing a single bounds check.

Old:

indexByteStringDenotation xs n = do
  unless (n >= 0 && n < BS.length xs) $
    fail "Index out of bounds"
  pure $ BS.index xs n

New:

indexByteStringDenotation xs n =
  maybe (fail "Index out of bounds") pure $ BS.indexMaybe xs n

GHC Core verification

effectfully suggested verifying that the intermediate Maybe from indexMaybe compiles away (see #7469). I dumped Core of PlutusCore.Evaluation.Machine.MachineParameters.Default (the module that exists specifically for this kind of inspection) and confirmed GHC eliminates the Maybe entirely. The optimized Core contains two primitive comparisons (<# and >=#) for bounds, then a direct readWord8OffAddr# (same primop as unsafeIndex). No Just/Nothing allocation on the hot path. In practice the compiled code is the same as a manual check + unsafeIndex.

Costing benchmark comparison

I ran benchmarks on plutus-bench for both old and new code to separate the denotation change from infrastructure drift.

Dataset CPU cost (picoseconds) Source
Historical parameters 13,169 builtinCostModelC.json, fitted March 2024
Old code, benchmarked today 189,953 commit 0c08eee6a (pre-#7699)
New code, benchmarked today 183,300 commit 1ae84fb1f (post-#7699)

The 14x gap between the historical value and today's numbers comes from changes in the benchmarking environment since March 2024 (machine or Nix config, not the code). The denotation change itself is a ~3.5% reduction, consistent with dropping one redundant bounds check from a constant-time operation.

@Unisay Unisay self-assigned this Apr 2, 2026
@Unisay Unisay requested a review from kwxm April 2, 2026 12:57
@Unisay Unisay marked this pull request as ready for review April 2, 2026 12:58
Re-ran costing benchmarks on plutus-bench for IndexByteString after
the denotation change in #7699. Updated CSV with 150 fresh data points
and CPU cost parameters in all three model variants (A, B, C):
13,169 -> 183,300 picoseconds (constant_cost).

The increase is due to benchmarking environment drift since the original
March 2024 measurements, not the code change itself. The denotation
change shows a ~3.5% improvement vs the old code on the same machine.
@Unisay Unisay changed the title Add IndexByteString cost model visualization Re-cost indexByteString and add cost model visualization Apr 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

Execution Budget Golden Diff

0c08eee (master) vs 880ff35

output

plutus-tx-plugin/test/Budget/9.6/show.golden.eval

Metric Old New Δ%
CPU 1_036_857_311 1_039_919_669 +0.30%

This comment will get updated when changes are made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

No Changelog Required Add this to skip the Changelog Check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant