Cost model for multiIndexArray (CIP-0156) - #7869
Draft
Unisay wants to merge 4 commits into
Draft
Conversation
Contributor
|
Unisay
force-pushed
the
yura/issue-2259-multi-index-array-costing
branch
from
July 29, 2026 17:17
74cd44d to
dcd569b
Compare
Adds the CPU and memory parameters for multiIndexArray to the model record, the JSON variants and the ledger API parameter lists. The CPU model is fitted through the ends of the benchmarked range rather than by least squares. Per-index time rises across that range, and least squares then returns a negative intercept, which adjustModel clamps away together with the fixed cost of a call.
Beyond the limit the execution time is not predictable from the index count alone, so the cost model cannot bound it; this is the same kind of limit as the ones on integerToByteString and replicateByte. It is far above any realistic use, since a 16384-byte transaction could not carry that many serialised indices even if it carried nothing else. The lookup moves into PlutusCore.Arrays, where the count is checked during the traversal rather than up front, since taking the length first would walk the list twice.
Index counts run from one to the limit, crossed with log-spaced array sizes, plus off-grid points and controls for element size. The index lists are given unfavourable spacing, so that the fit does not rest on the favourable spacing a straightforward generator produces; a few inputs, including the largest index count, are spaced as widely as a transaction's memory budget would allow, since those are the points the fit takes. makeBenchmarks becomes IO, because fixing the layout requires building the lists into compact regions.
…used The new page plots the benchmark data against the model plane and the per-index time distribution. All pages now read builtinCostModelE.json, the PlutusV3 model from PV 11 onwards, in place of C.
Unisay
force-pushed
the
yura/issue-2259-multi-index-array-costing
branch
from
July 29, 2026 17:52
dcd569b to
8cbcee0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the placeholder costing of
multiIndexArraywith a benchmarked model: CPU linear in the number of indices (linear_in_y), memory linear in the length of the result. The denotation forces each element read eagerly, asindexArraydoes, so the array access is paid for inside this builtin rather than wherever the element is later demanded. Resolves IntersectMBO/plutus-private#2259.The number of indices is limited to 4096, because beyond that the execution time is not predictable from the index count alone. This is the same kind of limit, for the same kind of reason, as the ones on
integerToByteStringandreplicateByte; see Note [Index count limitation for multiIndexArray]. It is far above any realistic use, since a 16384-byte transaction could not carry that many serialised indices even if it carried nothing else. It does need a CIP-0156 amendment, and it is much cheaper to add now than once the builtin is deployed.Benchmarks cross log-spaced array sizes from 1 to 131072 with index counts from 1 to the limit, using uniformly random indices, plus off-grid points and two control cells with 1 KiB elements. Neither array size nor element size affects the cost. The index lists are deliberately given unfavourable spacing, described in Note [Scattered index lists], because a list built the obvious way gets favourable spacing and fitting to that would understate the cost. A few inputs, including the largest index count, are spaced as widely as a transaction's memory budget would allow, since the fit takes the slowest observation at each end of the range.
The slope and intercept come from a line through the ends of the benchmarked range rather than from least squares. Per-index time rises slightly with the index count, and least squares on such data returns a negative intercept, which
adjustModelthen clamps, discarding the fixed cost of a call along with it. The fit is checked against every data point, and as a sanity check on the outcome a single-indexmultiIndexArrayis charged 311,081 ps againstindexArray's 232,010, which is the right ordering because it does strictly more work.ParamName entries for the four new parameters are appended to V1, V2 and V3, following the batch-6 precedent. A new page under
doc/cost-models/multiindexarrayplots the benchmark data against the model. Fitting the model locally requires working around theEqualsByteStringoff-diagonal data gap inmodels.R(see #7868).