Skip to content

Commit 7b9c8a9

Browse files
committed
Benchmark.Arrays
1 parent 52c8ebd commit 7b9c8a9

File tree

7 files changed

+98
-12
lines changed

7 files changed

+98
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{-# LANGUAGE BlockArguments #-}
2+
{-# LANGUAGE TypeApplications #-}
3+
4+
module Benchmarks.Arrays (makeBenchmarks) where
5+
6+
import Prelude
7+
8+
import Common (createOneTermBuiltinBench, createTwoTermBuiltinBenchElementwise)
9+
import Control.Monad (replicateM)
10+
import Criterion.Main (Benchmark)
11+
import Data.Vector.Strict (Vector)
12+
import Data.Vector.Strict qualified as Vector
13+
import PlutusCore.Builtin (mkTyBuiltin)
14+
import PlutusCore.Core (Type)
15+
import PlutusCore.Default (DefaultFun (IndexArray, LengthOfArray, ListToArray), DefaultUni)
16+
import PlutusCore.Name.Unique (TyName)
17+
import System.Random.Stateful (StdGen, UniformRange (uniformRM), runStateGen_)
18+
19+
--------------------------------------------------------------------------------
20+
-- Benchmarks ------------------------------------------------------------------
21+
22+
makeBenchmarks :: StdGen -> [Benchmark]
23+
makeBenchmarks gen =
24+
[ benchLengthOfArray gen
25+
, benchListToArray gen
26+
, benchIndexArray gen
27+
]
28+
29+
benchLengthOfArray :: StdGen -> Benchmark
30+
benchLengthOfArray gen =
31+
createOneTermBuiltinBench LengthOfArray [tyArrayOfInteger] listOfArrays
32+
where
33+
listOfArrays :: [Vector Integer] =
34+
runStateGen_ gen \g -> replicateM 100 do
35+
arraySize <- uniformRM (1, 100) g
36+
Vector.replicateM arraySize (uniformRM intRange g)
37+
38+
benchListToArray :: StdGen -> Benchmark
39+
benchListToArray gen =
40+
createOneTermBuiltinBench ListToArray [tyListOfInteger] listOfLists
41+
where
42+
listOfLists :: [[Integer]] =
43+
runStateGen_ gen \g -> replicateM 100 do
44+
listSize <- uniformRM (1, 100) g
45+
replicateM listSize (uniformRM intRange g)
46+
47+
benchIndexArray :: StdGen -> Benchmark
48+
benchIndexArray gen =
49+
createTwoTermBuiltinBenchElementwise
50+
IndexArray
51+
[tyArrayOfInteger]
52+
(zip arrays idxs)
53+
where
54+
(arrays :: [Vector Integer], idxs :: [Integer]) =
55+
unzip $ runStateGen_ gen \g -> replicateM 100 do
56+
arraySize <- uniformRM (1, 100) g
57+
vec <- Vector.replicateM arraySize (uniformRM intRange g)
58+
idx <- uniformRM (0, arraySize - 1) g
59+
pure (vec, fromIntegral idx)
60+
61+
--------------------------------------------------------------------------------
62+
-- Helpers ---------------------------------------------------------------------
63+
64+
tyListOfInteger :: Type TyName DefaultUni ()
65+
tyListOfInteger = mkTyBuiltin @_ @[Integer] ()
66+
67+
tyArrayOfInteger :: Type TyName DefaultUni ()
68+
tyArrayOfInteger = mkTyBuiltin @_ @(Vector Integer) ()
69+
70+
intRange :: (Integer, Integer)
71+
intRange =
72+
( fromIntegral (minBound @Int) - 10
73+
, fromIntegral (maxBound @Int) + 10
74+
)

plutus-core/cost-model/budgeting-bench/Common.hs

+3-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ benchWith
8484
-- the result, so e.g. 'evaluateCek' won't work properly because it returns a pair whose components
8585
-- won't be evaluated by 'whnf'. We can't use 'nf' because it does too much work: for instance if it
8686
-- gets back a 'Data' value it'll traverse all of it.
87-
benchWith params name term = bench name $ whnf (evaluateCekNoEmit params) term
87+
benchWith params name term =
88+
bench name $
89+
whnf (unsafeSplitStructuralOperational . evaluateCekNoEmit params) term
8890

8991
{- Benchmark with the most recent CekParameters -}
9092
benchDefault :: String -> PlainTerm DefaultUni DefaultFun -> Benchmark

plutus-core/cost-model/budgeting-bench/Main.hs

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module Main (main) where
33

44
import CriterionExtensions (BenchmarkingPhase (Continue, Start), criterionMainWith)
55

6+
import Benchmarks.Arrays qualified
67
import Benchmarks.Bitwise qualified
78
import Benchmarks.Bool qualified
89
import Benchmarks.ByteStrings qualified
@@ -53,6 +54,7 @@ main = do
5354
<> Benchmarks.Data.makeBenchmarks gen
5455
<> Benchmarks.Integers.makeBenchmarks gen
5556
<> Benchmarks.Lists.makeBenchmarks gen
57+
<> Benchmarks.Arrays.makeBenchmarks gen
5658
<> Benchmarks.Misc.makeBenchmarks gen
5759
<> Benchmarks.Pairs.makeBenchmarks gen
5860
<> Benchmarks.Strings.makeBenchmarks gen

plutus-core/cost-model/create-cost-model/BuiltinMemoryModels.hs

+3-3
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ builtinMemoryModels = BuiltinCostModelBase
173173
-- paramCaseList
174174
-- paramCaseData
175175
, paramDropList = Id $ ModelTwoArgumentsConstantCost 4
176-
, paramLengthOfArray = Id $ ModelOneArgumentConstantCost 99
177-
, paramListToArray = Id $ ModelOneArgumentConstantCost 99
178-
, paramIndexArray = Id $ ModelTwoArgumentsConstantCost 99
176+
, paramLengthOfArray = Id $ ModelOneArgumentConstantCost 10
177+
, paramListToArray = Id $ ModelOneArgumentLinearInX identityFunction
178+
, paramIndexArray = Id $ ModelTwoArgumentsConstantCost 32
179179
}
180180
where identityFunction = OneVariableLinearFunction 0 1

plutus-core/cost-model/data/models.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ modelFun <- function(path) {
785785

786786
dropListModel <- linearInX ("DropList")
787787

788-
## Arrays - TEMPORARY, but probably right
788+
## Arrays
789789
lengthOfArrayModel <- constantModel ("LengthOfArray")
790790
listToArrayModel <- linearInX ("ListToArray")
791791
indexArrayModel <- constantModel ("IndexArray")

plutus-core/plutus-core.cabal

+2
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,7 @@ executable cost-model-budgeting-bench
888888
import: lang
889889
main-is: Main.hs
890890
other-modules:
891+
Benchmarks.Arrays
891892
Benchmarks.Bitwise
892893
Benchmarks.Bool
893894
Benchmarks.ByteStrings
@@ -924,6 +925,7 @@ executable cost-model-budgeting-bench
924925
, random
925926
, text
926927
, time
928+
, vector
927929

928930
-- This reads CSV data generated by cost-model-budgeting-bench, uses R to build
929931
-- the cost models for built-in functions, and saves them in a specified

plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs

+13-7
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import PlutusCore.Data (Data (..))
2323
import PlutusCore.Default.Universe
2424
import PlutusCore.Evaluation.Machine.BuiltinCostModel
2525
import PlutusCore.Evaluation.Machine.ExBudgetStream (ExBudgetStream)
26-
import PlutusCore.Evaluation.Machine.ExMemoryUsage (ExMemoryUsage, IntegerCostedLiterally (..),
26+
import PlutusCore.Evaluation.Machine.ExMemoryUsage (ArrayCostedByLength, ExMemoryUsage,
27+
IntegerCostedLiterally (..),
2728
ListCostedByLength (..),
2829
NumBytesCostedAsNumWords (..), memoryUsage,
2930
singletonRose)
@@ -2107,25 +2108,30 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
21072108
(runCostingFunTwoArguments . paramDropList)
21082109

21092110
toBuiltinMeaning _semvar LengthOfArray =
2110-
let lengthOfArrayDenotation :: SomeConstant uni (Vector a) -> BuiltinResult Int
2111+
let lengthOfArrayDenotation :: SomeConstant uni (ArrayCostedByLength a) -> BuiltinResult Int
21112112
lengthOfArrayDenotation (SomeConstant (Some (ValueOf uni vec))) =
21122113
case uni of
21132114
DefaultUniArray _uniA -> pure $ Vector.length vec
21142115
_ -> throwing _StructuralUnliftingError "Expected an array but got something else"
21152116
{-# INLINE lengthOfArrayDenotation #-}
2116-
in makeBuiltinMeaning lengthOfArrayDenotation (runCostingFunOneArgument . unimplementedCostingFun)
2117+
in makeBuiltinMeaning lengthOfArrayDenotation (runCostingFunOneArgument . paramLengthOfArray)
21172118

21182119
toBuiltinMeaning _semvar ListToArray =
2119-
let listToArrayDenotation :: SomeConstant uni [a] -> BuiltinResult (Opaque val (Vector a))
2120+
let listToArrayDenotation
2121+
:: SomeConstant uni (ListCostedByLength a)
2122+
-> BuiltinResult (Opaque val (Vector a))
21202123
listToArrayDenotation (SomeConstant (Some (ValueOf uniListA xs))) =
21212124
case uniListA of
21222125
DefaultUniList uniA -> pure $ fromValueOf (DefaultUniArray uniA) $ Vector.fromList xs
21232126
_ -> throwing _StructuralUnliftingError "Expected an array but got something else"
21242127
{-# INLINE listToArrayDenotation #-}
2125-
in makeBuiltinMeaning listToArrayDenotation (runCostingFunOneArgument . unimplementedCostingFun)
2128+
in makeBuiltinMeaning listToArrayDenotation (runCostingFunOneArgument . paramListToArray)
21262129

21272130
toBuiltinMeaning _semvar IndexArray =
2128-
let indexArrayDenotation :: SomeConstant uni (Vector a) -> Int -> BuiltinResult (Opaque val a)
2131+
let indexArrayDenotation
2132+
:: SomeConstant uni (ArrayCostedByLength a)
2133+
-> Int
2134+
-> BuiltinResult (Opaque val a)
21292135
indexArrayDenotation (SomeConstant (Some (ValueOf uni vec))) n =
21302136
case uni of
21312137
DefaultUniArray arg -> do
@@ -2138,7 +2144,7 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
21382144
-- message, so we don't need to repeat them here.
21392145
throwing _StructuralUnliftingError "Expected an array but got something else"
21402146
{-# INLINE indexArrayDenotation #-}
2141-
in makeBuiltinMeaning indexArrayDenotation (runCostingFunTwoArguments . unimplementedCostingFun)
2147+
in makeBuiltinMeaning indexArrayDenotation (runCostingFunTwoArguments . paramIndexArray)
21422148

21432149
-- See Note [Inlining meanings of builtins].
21442150
{-# INLINE toBuiltinMeaning #-}

0 commit comments

Comments
 (0)