# Сложность скрипта
Сложность скрипта — безразмерная величина, которая оценивает вычислительные ресурсы, необходимые для исполнения скрипта.
Сложность скрипта складывается из сложностей всех используемых функций и операторов. Например, оператор ::
имеет сложность 1, а функция проверки подписи sigVerify()
имеет сложность 180.
Для скрипта dApp отдельно рассчитывается сложность каждой вызываемой функции и сложность функции-верификатора.
Ограничения на сложность скрипта приведены в разделе Ограничения.
Узнать сложность скрипта можно в Waves IDE:
Фактическая сложность при выполнении скрипта может оказаться меньше, чем сложность, рассчитанная при компиляции.
# Функции
Сложность встроенных функций представлена в разделе Встроенные функции.
Сложность вызова функции равна максимуму из двух чисел: 1 и сложности возвращаемого выражения. Таким образом, вызов любой функции имеет сложность не менее 1, даже если функция ничего не делает.
# Операторы
Сложность операторов представлена в разделе Операторы.
# Ветвления
Сложность скрипта с ветвлениями (if ... then ... else
) при компиляции рассчитывается по самой сложной ветке. Учитывается также сложность условия.
match ... case
имеет сложность, равную количеству case
, при этом каждый тип в объединении (например, case n: Int|BigInt
) учитывается как отдельный case
. Если отсутствует условие по умолчанию (case _
), к сложности добавляется еще 1.
# Структуры, кортежи, списки
Сложность конструктора структуры или кортежа при компиляции скрипта считается равной количеству элементов. Фактическая сложность конструктора при выполнении скрипта равна 1.
Сложность создания списка равна количеству элементов, поскольку выражение [a, b, c]
эквивалентно a :: b :: c :: nil
.
# Макросы, разворачиваемые при компиляции
as
имеет сложность 1.Следующий код
let x = 1.as[Int]
разворачивается в
let x = { let @ = 1 if ($isInstanceOf(@, "Int")) # Сложность 1 then @ else unit }
exactAs
имеет сложность 4.let x = someExpr.exactAs[Int]
разворачивается в
let x = { let @ = someExpr if ($isInstanceOf(@, "Int")) # Сложность 1 then @ else throw(($getType(someExpr) + " couldn't be cast to Int")) # Сложность 3: 1 а throw, 1 за getType, 1 за "+" }
FOLD<N>(list, start, foldFunc)
имеет сложность 4 +N
× (3 + сложность_foldFunc
).let x = FOLD<5>(list, 0, foldFunc)
разворачивается в
let x = { let $l = list let $s = size($l) # Сложность 2 let $acc0 = 0 # Сложность 3 + сложность_foldFunc func $f0_1($a,$i) = if ($i >= $s) # Сложность 1 then $a else foldFunc($a, $l[$i]) # Сложность foldFunc + 2 за обращение по индексу # Сложность 2 func $f0_2($a,$i) = if ($i >= $s) # Сложность 1 then $a else throw("List size exceeds 5") # Сложность 1 # 1 вызов $f0_2 и 5 вызовов $f0_1 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5) }
strict
имеет сложность 1. Если выражение ниже имеет сложность 0, то к сложности, учитываемой при компиляции, добавляется еще 1.strict x = someExpr restExpr
разворачивается в
let x = someExpr if (x == x) # Сложность 1 then restExpr else throw("Strict value is not equal to itself.") # Сложность 1