-
Notifications
You must be signed in to change notification settings - Fork 486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Costing of BuiltinArray functions #6950
base: master
Are you sure you want to change the base?
Conversation
3865759
to
66501da
Compare
66501da
to
c891dcc
Compare
c891dcc
to
7b9c8a9
Compare
benchWith params name term = bench name $ whnf (evaluateCekNoEmit params) term | ||
benchWith params name term = | ||
bench name $ | ||
whnf (unsafeSplitStructuralOperational . evaluateCekNoEmit params) term |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes a benchmark fail if evaluation fails (wasn't the case before)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could add a comment to remind us why unsafeSplitStructuralOperational
is there, since it's not immediately obvious what it's doing.
, paramLengthOfArray = Id $ ModelOneArgumentConstantCost 10 | ||
, paramListToArray = Id $ ModelOneArgumentLinearInX identityFunction | ||
, paramIndexArray = Id $ ModelTwoArgumentsConstantCost 32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kwxm 10
and 32
here are magic
numbers I chose because they were chose in similar builtin functions. This is not based on any measurements I did whatsoever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what we should put for the memory costs. I guess for ListToArray
we'll need something with a non-zero constant term to account for some header data and then one pointer's worth of memory for each entry. @effectfully Do you remember how much room a pointer takes up?
For LengthOfArray
we'll need enough memory to hold one integer, so maybe a constant cost of 1 would do, and for IndexArray
it'll again be one pointer's worth.
But then again, the current numbers are pretty similar to those for other things like LengthOfByteString
, so maybe these are OK. We charge 100 memory units for each CEK step anyway, so that dominates the memory cost and and extra 10 or 20 bytes for a builtin won't make a lot of difference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks mostly OK, although I think that the costing benchmarks need to have ArrayCostedByLength
wrappers. Apart from that it looks fine.
, paramLengthOfArray = Id $ ModelOneArgumentConstantCost 10 | ||
, paramListToArray = Id $ ModelOneArgumentLinearInX identityFunction | ||
, paramIndexArray = Id $ ModelTwoArgumentsConstantCost 32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what we should put for the memory costs. I guess for ListToArray
we'll need something with a non-zero constant term to account for some header data and then one pointer's worth of memory for each entry. @effectfully Do you remember how much room a pointer takes up?
For LengthOfArray
we'll need enough memory to hold one integer, so maybe a constant cost of 1 would do, and for IndexArray
it'll again be one pointer's worth.
But then again, the current numbers are pretty similar to those for other things like LengthOfByteString
, so maybe these are OK. We charge 100 memory units for each CEK step anyway, so that dominates the memory cost and and extra 10 or 20 bytes for a builtin won't make a lot of difference.
benchWith params name term = bench name $ whnf (evaluateCekNoEmit params) term | ||
benchWith params name term = | ||
bench name $ | ||
whnf (unsafeSplitStructuralOperational . evaluateCekNoEmit params) term |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could add a comment to remind us why unsafeSplitStructuralOperational
is there, since it's not immediately obvious what it's doing.
|
||
benchLengthOfArray :: StdGen -> Benchmark | ||
benchLengthOfArray gen = | ||
createOneTermBuiltinBench LengthOfArray [tyArrayOfInteger] listOfArrays |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to use the create<N>TermBudgetingBenchWithWrappers
here to wrap the array arguments, like this, although that will only really matter for listToArray
since the others are constant time. We have to use the same size measures here as are used in the denotations.
Try adding the wrappers and re-running the benchmarks and see if the cost of listToArray
changes significantly. If it does, you'll have to rebuild the cost model with the new results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking that we should probably make the costed-by-length measure the default one and maybe do the same for lists (although maybe then we'll need a wrapper that measures the entire memory footprint for some of the other things involving lists). I'll make an issue to look at that separately.
Closes https://github.com/IntersectMBO/plutus-private/issues/1375
Benchmark run: https://github.com/IntersectMBO/plutus/actions/runs/13907860876
(^ not zoomed out)