Cost model for keepPolicies (CIP-0168) - #7930
Draft
Unisay wants to merge 3 commits into
Draft
Conversation
Unisay
changed the base branch from
master
to
yura/issue-2306-keep-drop-policies
September 1, 2026 12:37
Unisay
force-pushed
the
yura/issue-2310-keep-policies-costing
branch
from
September 2, 2026 08:44
b7c3892 to
ae4a298
Compare
Contributor
|
Unisay
force-pushed
the
yura/issue-2310-keep-policies-costing
branch
from
September 2, 2026 09:15
ae4a298 to
e491998
Compare
Unisay
force-pushed
the
yura/issue-2310-keep-policies-costing
branch
from
September 2, 2026 10:10
e491998 to
3dc9dba
Compare
Base automatically changed from
yura/issue-2306-keep-drop-policies
to
master
September 3, 2026 11:57
Every point of the main sweep is the costliest input for its pair of sizes: the builtin skips the part of the outer map the list cannot reach, so the pairs that cost anything are the pairs the list names, and packing them into as few policies as the list covers puts all of them in reach. The list length and the total size are sampled log-uniformly and independently, and two sweeps hold both fixed while varying what a cost model cannot see: the policy count and how much of the list hits. Both move the cost, so no model of the two sizes is right everywhere, and these sweeps are what measures how far wrong it gets. The shape sweep runs against a short list as well as a long one, because the list term swamps the `Value` term once the list is long. The points with an empty `Value` double as a control on the rig: the builtin returns before it looks at the list there, so the same list costs about a hundredth of what it costs against a `Value` that is not empty. A benchmark that floated the list work out of the measured loop would show no such gap. Shares the log-uniform sampler and the `Value` generator with the `policies` benchmark, which had its own copies of both.
Linear in the length of the policy list and in `Value.totalSize`, which is what `instance ExMemoryUsage Value` already reports, so the denotation needs no size wrapper. Five parameters, fitted against semantics variant E, which is what PlutusV3 and PlutusV4 map to. The fit undercharges 8 of its 126 points, at worst by 1.28x and in seven of the eight by between 1.01x and 1.18x. That is the file's normal condition: scored the same way against their own rows, the shipped `addInteger` undercharges 48% of its 225 rows, `appendByteString` 59% of 441 and `valueContains` 49% of 1158, none by more than 1.2x. Points with an empty outer map are left out of the fit, because the builtin returns before it looks at the list and an element costs single-digit nanoseconds there against the hundreds the real work costs. Scoring on only the 120 rows the fit sees gives 7 undercharges rather than 8. Memory is six words per new outer-map node, at most one per pair in the result: the result shares the inner maps wholesale and the policy ids by pointer, so the outer spine is the only new structure. Implements IntersectMBO/plutus-private#2310.
One 3D plot: list length against `Value.totalSize` against time, with the measured points in blue and the model's charge for the same inputs in red. The spread at a fixed pair of sizes is what no model of those two numbers can capture, and in three dimensions it reads straight off the plot. The page computes a least-squares fit from the CSV it has already loaded and reports it beside the shipped coefficients, so the figures follow whatever data the page is pointed at rather than the JSON alone. `fitLinearInXAndY` in the shared code does that and reproduces what `models.R` gets from the same rows. The plot panel is created in `renderPlots` rather than declared in the page, because the shared loader replaces the contents of `#plot-container` with its own status message before it calls the page's render. Every other page targets that container itself, so nothing there noticed.
Unisay
force-pushed
the
yura/issue-2310-keep-policies-costing
branch
from
September 3, 2026 11:57
3dc9dba to
b181995
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.
Adds the cost model for
keepPolicies, five parameters: CPU linear in the length of the policy list and inValue.totalSize, memory linear inValue.totalSize. The denotation takes the plainValue, becauseinstance ExMemoryUsage Valuealready reportstotalSize.ValueOuterSizeis not the measure here even thoughkeepPolicieslooks likepoliciesfrom the outside: it reports the policy count, so aValueof one policy holding 10000 tokens would be measured as size 1 whilepack'folds all 10000 pairs.Memory is six words per new outer-map node, at most one per pair in the result. The result shares the inner maps wholesale and the policy ids by pointer, so the outer spine is the only new structure.
Implements IntersectMBO/plutus-private#2310.