# Script complexity
Script complexity is a dimensionless value that represents computational resources required to execute the script.
The complexity of a script is the sum of complexities of all the functions and operators used. For example, the ::
operator has complexity 1, and the sigVerify()
function has complexity 180.
For a dApp script, the complexity of each callable function and the complexity of the verifier function are calculated separately.
Limitations on the script complexity are given in the Limitations article.
You can find out the script complexity in Waves IDE:
The actual complexity when executing the script may be less than the complexity calculated at compilation.
# Functions
The complexity of built-in functions is listed in the Built-in Functions article.
The complexity of a function call is the maximum of two numbers: 1 and the complexity of the expression returned. Thus, function call has a complexity of at least 1, even if the function does nothing.
# Operators
The complexity of operators is listed in the Operators article.
# Conditional Statements
The complexity of a script with branches (if ... then ... else
) is calculated at compilation by the most complex branch. The complexity of the condition is also taken into account.
The complexity of match ... case
equals to the number of case
, with each type in the union (for example, case n: Int|BigInt
) counted as a separate case
. If there is no default case (case _
), another 1 is added to the complexity.
# Structures, Tuples, Lists
The complexity of a constructor of structure or tuple is considered equal to the number of elements at compilation. The actual constructor complexity when executing the script is 1.
The complexity of creating a list is equal to the number of elements, since the expression [a, b, c]
is equivalent to a :: b :: c :: nil
.
# Macros Expanded at Compilation
as
has complexity 1.The following code
let x = 1.as[Int]
expands into
let x = { let @ = 1 if ($isInstanceOf(@, "Int")) # Complexity is 1 then @ else unit }
exactAs
has complexity 4.let x = someExpr.exactAs[Int]
expands into
let x = { let @ = someExpr if ($isInstanceOf(@, "Int")) # Complexity is 1 then @ else throw(($getType(someExpr) + " couldn't be cast to Int")) # Complexity is 3: 1 for throw, 1 for getType, and 1 for "+" }
FOLD<N>(list, start, foldFunc)
has complexity 4 +N
× (3 + complexity_of_foldFunc
).let x = FOLD<5>(list, 0, foldFunc)
expands into
let x = { let $l = list let $s = size($l) # Complexity is 2 let $acc0 = 0 # Complexity is 3 + complexity_of_foldFunc func $f0_1($a,$i) = if ($i >= $s) # Complexity is 1 then $a else foldFunc($a, $l[$i]) # Complexity of foldFunc + 2 for accessing a list item # Complexity is 2 func $f0_2($a,$i) = if ($i >= $s) # Complexity is 1 then $a else throw("List size exceeds 5") # Complexity is 1 # 1 call of $f0_2 and 5 calls of $f0_1 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5) }
strict
has complexity 1. If the expression below has complexity 0, another 1 is added to the complexity at compilation.strict x = someExpr restExpr
expands into
let x = someExpr if (x == x) # Complexity is 1 then restExpr else throw("Strict value is not equal to itself.") # Complexity is 1