@@ -11,6 +11,7 @@ import Prelude
1111
1212import Common
1313import Control.Monad (replicateM )
14+ import Control.Monad.State.Strict (State )
1415import Criterion.Main (Benchmark )
1516import Data.Bits (shiftR , (.&.) )
1617import Data.ByteString (ByteString )
@@ -19,13 +20,13 @@ import Data.Int (Int64)
1920import Data.List (find , sort )
2021import Data.Word (Word8 )
2122import GHC.Stack (HasCallStack )
22- import PlutusCore (DefaultFun (LookupCoin , UnValueData , ValueContains , ValueData ))
23+ import PlutusCore (DefaultFun (InsertCoin , LookupCoin , UnValueData , ValueContains , ValueData ))
2324import PlutusCore.Builtin (BuiltinResult (BuiltinFailure , BuiltinSuccess , BuiltinSuccessWithLogs ))
2425import PlutusCore.Evaluation.Machine.ExMemoryUsage (ValueLogOuterSizeAddLogMaxInnerSize (.. ),
2526 ValueTotalSize (.. ))
26- import PlutusCore.Value (K , Value )
27+ import PlutusCore.Value (K , Quantity ( .. ), Value )
2728import PlutusCore.Value qualified as Value
28- import System.Random.Stateful (StatefulGen , StdGen , runStateGen_ , uniformRM )
29+ import System.Random.Stateful (StateGenM , StatefulGen , StdGen , runStateGen_ , uniformRM )
2930
3031----------------------------------------------------------------------------------------------------
3132-- Benchmarks --------------------------------------------------------------------------------------
@@ -36,6 +37,7 @@ makeBenchmarks gen =
3637 , valueContainsBenchmark gen
3738 , valueDataBenchmark gen
3839 , unValueDataBenchmark gen
40+ , insertCoinBenchmark gen
3941 ]
4042
4143----------------------------------------------------------------------------------------------------
@@ -47,10 +49,10 @@ lookupCoinBenchmark gen =
4749 (id , id , ValueLogOuterSizeAddLogMaxInnerSize ) -- Wrap Value argument to report sum of log sizes
4850 LookupCoin -- the builtin fun
4951 [] -- no type arguments needed (monomorphic builtin)
50- (lookupCoinArgs gen) -- the argument combos to generate benchmarks for
52+ (runBenchGen gen lookupCoinArgs ) -- the argument combos to generate benchmarks for
5153
52- lookupCoinArgs :: StdGen -> [(ByteString , ByteString , Value )]
53- lookupCoinArgs gen = runStateGen_ gen \ (g :: g ) -> do
54+ lookupCoinArgs :: ( StatefulGen g m ) => g -> m [(ByteString , ByteString , Value )]
55+ lookupCoinArgs gen = do
5456 {- Exhaustive power-of-2 combinations for BST worst-case benchmarking.
5557
5658 Tests all combinations of sizes from powers and half-powers of 2.
@@ -81,7 +83,7 @@ lookupCoinArgs gen = runStateGen_ gen \(g :: g) -> do
8183
8284 sequence
8385 -- Generate worst-case lookups for each size combination
84- [ withWorstCaseSearchKeys (generateConstrainedValueWithMaxPolicy numPolicies tokensPerPolicy g )
86+ [ withWorstCaseSearchKeys (generateConstrainedValueWithMaxPolicy numPolicies tokensPerPolicy gen )
8587 | numPolicies <- sizes
8688 , tokensPerPolicy <- sizes
8789 ]
@@ -211,6 +213,41 @@ unValueDataBenchmark :: StdGen -> Benchmark
211213unValueDataBenchmark gen =
212214 createOneTermBuiltinBench UnValueData [] (Value. valueData <$> generateTestValues gen)
213215
216+ ----------------------------------------------------------------------------------------------------
217+ -- InsertCoin --------------------------------------------------------------------------------------
218+
219+ insertCoinBenchmark :: StdGen -> Benchmark
220+ insertCoinBenchmark gen =
221+ createFourTermBuiltinBenchElementwiseWithWrappers
222+ (id , id , id , ValueLogOuterSizeAddLogMaxInnerSize )
223+ InsertCoin
224+ []
225+ (runBenchGen gen insertCoinArgs)
226+
227+ insertCoinArgs :: (StatefulGen g m ) => g -> m [(ByteString , ByteString , Integer , Value )]
228+ insertCoinArgs gen = do
229+ lookupArgs <- lookupCoinArgs gen
230+ let noOfBenchs = length lookupArgs
231+ amounts <- genZeroOrMaxAmount gen noOfBenchs
232+ pure $ reorderArgs <$> zip lookupArgs amounts
233+ where
234+ reorderArgs ((b1, b2, val), am) = (b1, b2, am, val)
235+
236+ -- | Generate either zero or maximum amount Integer values, the probability of each is 50%
237+ genZeroOrMaxAmount
238+ :: (StatefulGen g m )
239+ => g
240+ -> Int
241+ -- ^ Number of amounts to generate
242+ -> m [Integer ]
243+ genZeroOrMaxAmount gen n =
244+ replicateM n $ do
245+ coinType <- uniformRM (0 :: Int , 1 ) gen
246+ pure $ case coinType of
247+ 0 -> 0
248+ 1 -> unQuantity maxBound
249+ _ -> error " genZeroOrMaxAmount: impossible"
250+
214251----------------------------------------------------------------------------------------------------
215252-- Value Generators --------------------------------------------------------------------------------
216253
@@ -360,3 +397,8 @@ unsafeFromBuiltinResult = \case
360397 BuiltinSuccess x -> x
361398 BuiltinSuccessWithLogs _ x -> x
362399 BuiltinFailure _ err -> error $ " BuiltinResult failed: " <> show err
400+
401+ -- | Abstracted runner for computations using stateful random generator 'StdGen'
402+ runBenchGen :: StdGen -> (StateGenM StdGen -> State StdGen a ) -> a
403+ runBenchGen gen ma = runStateGen_ gen \ g -> ma g
404+
0 commit comments