Skip to content

Commit

Permalink
Miniev implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
phearnot committed Aug 15, 2023
1 parent f4ab799 commit 0aee7c1
Show file tree
Hide file tree
Showing 95 changed files with 2,443 additions and 1,946 deletions.
15 changes: 7 additions & 8 deletions benchmark/src/main/scala/com/wavesplatform/state/DBState.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@ abstract class DBState extends ScorexLogging {
AddressScheme.current = new AddressScheme { override val chainId: Byte = 'W' }

lazy val environment = new WavesEnvironment(
AddressScheme.current.chainId,
Coeval.raiseError(new NotImplementedError("`tx` is not implemented")),
Coeval(rocksDBWriter.height),
rocksDBWriter,
null,
DirectiveSet.contractDirectiveSet,
ByteStr.empty
)
???,
???,
ByteStr.empty,
DirectiveSet.contractDirectiveSet,
) {
override def blockchain: Blockchain = ???
}

@TearDown
def close(): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ object EnvironmentFunctionsBenchmark {

@State(Scope.Benchmark)
class AddressFromString {
val ctx: EvaluationContext[Environment, Id] =
val ctx: EvaluationContext[Id] =
WavesContext
.build(Global, DirectiveSet(V4, Account, DApp).explicitGet(), true)
.evaluationContext(environment)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ package com.wavesplatform.lang.v1
import java.util.concurrent.TimeUnit
import cats.Id
import com.wavesplatform.lang.Common
import com.wavesplatform.lang.directives.values.{V1, V3}
import com.wavesplatform.lang.directives.values.{V1, V3, V5, V6}
import com.wavesplatform.lang.v1.EvaluatorV2Benchmark.*
import com.wavesplatform.lang.v1.compiler.Terms.{EXPR, IF, TRUE}
import com.wavesplatform.lang.v1.compiler.Terms.{CONST_LONG, EXPR, IF, TRUE}
import com.wavesplatform.lang.v1.compiler.TestCompiler
import com.wavesplatform.lang.v1.evaluator.EvaluatorV2
import com.wavesplatform.lang.v1.evaluator.ctx.{DisabledLogEvaluationContext, EvaluationContext}
import com.wavesplatform.lang.v1.evaluator.ctx.impl.PureContext
import com.wavesplatform.lang.v1.traits.Environment
import com.wavesplatform.lang.v1.evaluator.ctx.{DisabledLogEvaluationContext, EvaluationContext, LoggedEvaluationContext}
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole

import scala.annotation.tailrec

object EvaluatorV2Benchmark {
val pureContext: CTX[Environment] = PureContext.build(V1, useNewPowPrecision = true).withEnvironment[Environment]
val pureEvalContext: EvaluationContext[Environment, Id] = pureContext.evaluationContext(Common.emptyBlockchainEnvironment())
val evaluatorV2: EvaluatorV2 = new EvaluatorV2(DisabledLogEvaluationContext(pureEvalContext), V1, true, true, false)
val pureContext: CTX = PureContext.build(V1, useNewPowPrecision = true)
val pureEvalContext: EvaluationContext[Id] = pureContext.evaluationContext(Common.emptyBlockchainEnvironment())
val evaluatorV2: EvaluatorV2 = new EvaluatorV2(DisabledLogEvaluationContext(pureEvalContext), V1, true, true, false)
}

@OutputTimeUnit(TimeUnit.MILLISECONDS)
Expand All @@ -43,6 +43,45 @@ class EvaluatorV2Benchmark {

@Benchmark
def conditions(st: Conditions, bh: Blackhole): Unit = bh.consume(eval(pureEvalContext, st.expr, V1))

@Benchmark
def recFunc(st: RecFunc, bh: Blackhole): Unit = bh.consume {
val (_, _, res) = eval(pureEvalContext, st.expr, V1)
require(res == Right(CONST_LONG(13631488)), s"$res")
}

@Benchmark
def overheadCallable(st: OverheadTest, bh: Blackhole): Unit = bh.consume {
val (_, comp, res) = eval(pureEvalContext, st.expr.expr, V6)
require((Int.MaxValue - comp) == 1048576, s"$comp")
}

@Benchmark
def mini_funcs(st: Funcs, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))

@Benchmark
def mini_lets(st: Lets, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))

@Benchmark
def mini_custom(st: CustomFunc, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))

@Benchmark
def mini_littleCustom(st: LittleCustomFunc, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))

@Benchmark
def mini_conditions(st: Conditions, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))

@Benchmark
def mini_recFunc(st: RecFunc, bh: Blackhole): Unit = bh.consume {
val (log, spentComplexity, res) = miniEv(st.expr, pureEvalContext)
require(res == Right(CONST_LONG(13631488)), s"$res")
}

@Benchmark
def mini_overheadCallable(st: OverheadTest, bh: Blackhole): Unit = bh.consume {
val (_, comp, res) = miniEv(st.expr.expr, pureEvalContext, 52000)
require(comp == 1048576, s"$comp")
}
}

@State(Scope.Benchmark)
Expand All @@ -57,7 +96,10 @@ class Funcs {
| a$count() == a$count()
""".stripMargin

val expr = TestCompiler(V3).compileExpression(script).expr.asInstanceOf[EXPR]
val expr = {
val sc = TestCompiler(V6).compileExpression(script, checkSize = false)
sc.expr
}
}

@State(Scope.Benchmark)
Expand All @@ -70,7 +112,22 @@ class Lets {
| a$count == a$count
""".stripMargin

val expr = TestCompiler(V3).compileExpression(script).expr.asInstanceOf[EXPR]
val expr = TestCompiler(V3).compileExpression(script, checkSize = false).expr
}

@State(Scope.Benchmark)
class RecFunc {
def scriptStr(size: Int) =
s"""func f1(i: Int) = i + 1
|${(2 to size)
.map { i =>
s"func f$i(${(0 until i).map(idx => s"i$idx: Int").mkString(",")}) = ${(1 until i).map(fi => s"f$fi(${(1 to fi).map(ii => s"i$ii").mkString(",")})").mkString("+")}"
}
.mkString("\n")}
|f${size}(${(1 to size).mkString(",")})
|""".stripMargin
private val script: String = scriptStr(22)
val expr = TestCompiler(V6).compileExpression(script, checkSize = false).expr
}

@State(Scope.Benchmark)
Expand Down Expand Up @@ -114,7 +171,7 @@ class CustomFunc {
| f() && f() && f() && f() && f() && f() && f()
""".stripMargin

val expr = TestCompiler(V3).compileExpression(script).expr.asInstanceOf[EXPR]
val expr = TestCompiler(V6).compileExpression(script).expr
}

@State(Scope.Benchmark)
Expand Down Expand Up @@ -158,7 +215,22 @@ class LittleCustomFunc {
| f()
""".stripMargin

val expr = TestCompiler(V3).compileExpression(script).expr.asInstanceOf[EXPR]
val expr = TestCompiler(V3).compileExpression(script).expr
}

@State(Scope.Benchmark)
class OverheadTest {
val expr = {
val n = 20
val scriptTest =
s"""
| func f0() = true
| ${(0 until n).map(i => s"func f${i + 1}() = if (f$i()) then f$i() else f$i()").mkString("\n")}
| f$n()
""".stripMargin
println(scriptTest)
TestCompiler(V5).compileExpression(scriptTest)
}
}

@State(Scope.Benchmark)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ import java.util.concurrent.{ThreadLocalRandom, TimeUnit}
import cats.Id
import com.google.common.primitives.Longs
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.common.utils._
import com.wavesplatform.common.utils.*
import com.wavesplatform.lang.directives.DirectiveSet
import com.wavesplatform.lang.directives.values._
import com.wavesplatform.lang.utils._
import com.wavesplatform.lang.directives.values.*
import com.wavesplatform.lang.utils.*
import com.wavesplatform.lang.v1.FunctionHeader.Native
import com.wavesplatform.lang.v1.PureFunctionsRebenchmark._
import com.wavesplatform.lang.v1.PureFunctionsRebenchmark.*
import com.wavesplatform.lang.v1.compiler.Terms
import com.wavesplatform.lang.v1.compiler.Terms._
import com.wavesplatform.lang.v1.compiler.Terms.*
import com.wavesplatform.lang.v1.evaluator.ctx.EvaluationContext
import com.wavesplatform.lang.v1.evaluator.ctx.impl.PureContext
import com.wavesplatform.lang.v1.evaluator.{FunctionIds, Log}
import com.wavesplatform.lang.v1.traits.Environment
import com.wavesplatform.lang.{Common, ExecutionError, v1}
import org.openjdk.jmh.annotations._
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole

import scala.util.Random
Expand Down Expand Up @@ -217,7 +216,7 @@ class PureFunctionsRebenchmark {
}

object PureFunctionsRebenchmark {
val context: EvaluationContext[Environment, Id] =
val context: EvaluationContext[Id] =
lazyContexts((DirectiveSet(V5, Account, Expression).explicitGet(), true, true))()
.evaluationContext(Common.emptyBlockchainEnvironment())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,27 @@ import cats.kernel.Monoid
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.common.utils.{Base58, EitherExt2}
import com.wavesplatform.crypto.Curve25519
import com.wavesplatform.lang.Global
import com.wavesplatform.lang.directives.values.{V1, V4}
import com.wavesplatform.lang.v1.EnvironmentFunctionsBenchmark.{curve25519, randomBytes}
import com.wavesplatform.lang.v1.FunctionHeader.Native
import com.wavesplatform.lang.v1.ScriptEvaluatorBenchmark.*
import com.wavesplatform.lang.v1.compiler.Terms.*
import com.wavesplatform.lang.v1.evaluator.Contextful.NoContext
import com.wavesplatform.lang.v1.evaluator.EvaluatorV1.*
import com.wavesplatform.lang.v1.evaluator.FunctionIds.{FROMBASE58, SIGVERIFY, TOBASE58}
import com.wavesplatform.lang.v1.evaluator.ctx.EvaluationContext
import com.wavesplatform.lang.v1.evaluator.ctx.impl.{CryptoContext, PureContext}
import com.wavesplatform.lang.v1.evaluator.{EvaluatorV1, FunctionIds}
import com.wavesplatform.lang.{Common, Global}
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole

import scala.util.Random

object ScriptEvaluatorBenchmark {
val version = V1
val pureEvalContext: EvaluationContext[NoContext, Id] =
PureContext.build(V1, useNewPowPrecision = true).evaluationContext
val evaluatorV1: EvaluatorV1[Id, NoContext] = new EvaluatorV1[Id, NoContext]()
val pureEvalContext: EvaluationContext[Id] =
PureContext.build(V1, useNewPowPrecision = true).evaluationContext(Common.emptyBlockchainEnvironment())
val evaluatorV1: EvaluatorV1[Id] = new EvaluatorV1[Id]()
}

@OutputTimeUnit(TimeUnit.MICROSECONDS)
Expand Down Expand Up @@ -93,7 +92,7 @@ class ScriptEvaluatorBenchmark {

@State(Scope.Benchmark)
class NestedBlocks {
val context: EvaluationContext[NoContext, Id] = pureEvalContext
val context: EvaluationContext[Id] = pureEvalContext

val expr: EXPR = {
val blockCount = 300
Expand All @@ -107,8 +106,9 @@ class NestedBlocks {

@State(Scope.Benchmark)
class Base58Perf {
val context: EvaluationContext[NoContext, Id] =
Monoid.combine(pureEvalContext, CryptoContext.build(Global, version).evaluationContext)
val context: EvaluationContext[Id] =
Monoid.combine(PureContext.build(V1, useNewPowPrecision = true), CryptoContext.build(Global, version))
.evaluationContext(Common.emptyBlockchainEnvironment())

val encode: EXPR = {
val base58Count = 120
Expand Down Expand Up @@ -150,8 +150,8 @@ class Base58Perf {

@State(Scope.Benchmark)
class Signatures {
val context: EvaluationContext[NoContext, Id] =
Monoid.combine(pureEvalContext, CryptoContext.build(Global, version).evaluationContext)
val context: EvaluationContext[Id] =
Monoid.combine(PureContext.build(V1, useNewPowPrecision = true), CryptoContext.build(Global, version)).evaluationContext(Common.emptyBlockchainEnvironment())

val expr: EXPR = {
val sigCount = 20
Expand Down Expand Up @@ -191,7 +191,7 @@ class Signatures {

@State(Scope.Benchmark)
class Concat {
val context: EvaluationContext[NoContext, Id] = pureEvalContext
val context: EvaluationContext[Id] = pureEvalContext

private val Steps = 180

Expand All @@ -218,7 +218,7 @@ class Concat {

@State(Scope.Benchmark)
class Median {
val context: EvaluationContext[NoContext, Id] = PureContext.build(V4, useNewPowPrecision = true).evaluationContext
val context: EvaluationContext[Id] = PureContext.build(V4, useNewPowPrecision = true).evaluationContext(Common.emptyBlockchainEnvironment())

val randomElements: Array[EXPR] =
(1 to 10000).map { _ =>
Expand Down Expand Up @@ -260,8 +260,8 @@ class Median {

@State(Scope.Benchmark)
class SigVerify32Kb {
val context: EvaluationContext[NoContext, Id] =
Monoid.combine(PureContext.build(V4, useNewPowPrecision = true).evaluationContext, CryptoContext.build(Global, V4).evaluationContext)
val context: EvaluationContext[Id] =
Monoid.combine(PureContext.build(V4, useNewPowPrecision = true), CryptoContext.build(Global, V4)).evaluationContext(Common.emptyBlockchainEnvironment())

val expr: EXPR = {
val (privateKey, publicKey) = curve25519.generateKeypair
Expand All @@ -281,11 +281,11 @@ class SigVerify32Kb {

@State(Scope.Benchmark)
class ListRemoveByIndex {
val context: EvaluationContext[NoContext, Id] =
val context: EvaluationContext[Id] =
Monoid.combine(
PureContext.build(V4, useNewPowPrecision = true).evaluationContext,
CryptoContext.build(Global, V4).evaluationContext
)
PureContext.build(V4, useNewPowPrecision = true),
CryptoContext.build(Global, V4)
).evaluationContext(Common.emptyBlockchainEnvironment())

val list: ARR = ARR(Vector.fill(1000)(CONST_LONG(Long.MaxValue)), limited = true).explicitGet()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.wavesplatform.lang

import cats.Id
import com.wavesplatform.lang.directives.values.StdLibVersion
import com.wavesplatform.lang.miniev.{Ev, State}
import com.wavesplatform.lang.v1.FunctionHeader.Native
import com.wavesplatform.lang.v1.compiler.Terms
import com.wavesplatform.lang.v1.compiler.Terms.{CONST_BIGINT, CONST_LONG, EXPR, FUNCTION_CALL}
Expand All @@ -10,7 +11,6 @@ import com.wavesplatform.lang.v1.evaluator.FunctionIds.POW_BIGINT
import com.wavesplatform.lang.v1.evaluator.ctx.EvaluationContext
import com.wavesplatform.lang.v1.evaluator.ctx.impl.Rounding
import com.wavesplatform.lang.v1.evaluator.{EvaluatorV2, Log}
import com.wavesplatform.lang.v1.traits.Environment

package object v1 {
def pow(base: BigInt, basePrecision: Int, exponent: BigInt, exponentPrecision: Int, resultPrecision: Int): EXPR =
Expand All @@ -27,9 +27,12 @@ package object v1 {
)

def eval(
ctx: EvaluationContext[Environment, Id],
ctx: EvaluationContext[Id],
expr: EXPR,
stdLibVersion: StdLibVersion
): (Log[Id], Int, Either[ExecutionError, Terms.EVALUATED]) =
EvaluatorV2.applyCompleted(ctx, expr, LogExtraInfo(), stdLibVersion, newMode = true, correctFunctionCallScope = true, enableExecutionLog = false)

def miniEv(expr: EXPR, ctx: EvaluationContext[Id], limit: Int = Int.MaxValue): (Log[Id], Int, Either[ExecutionError, Terms.EVALUATED]) =
Ev.run(expr, ???)
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ object WavesEnvironmentBenchmark {
RDB.open(wavesSettings.dbSettings)
}

val environment: Environment[Id] = {
val environment: Environment[Id] = ???/*{
val state = new RocksDBWriter(rdb, wavesSettings.blockchainSettings, wavesSettings.dbSettings)
new WavesEnvironment(
AddressScheme.current.chainId,
Expand All @@ -146,7 +146,7 @@ object WavesEnvironmentBenchmark {
DirectiveSet.contractDirectiveSet,
ByteStr.empty
)
}
}*/

@TearDown
def close(): Unit = {
Expand Down
11 changes: 7 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ lazy val lang =

lazy val `lang-jvm` = lang.jvm
.settings(
name := "RIDE Compiler",
normalizedName := "lang",
description := "The RIDE smart contract language compiler",
libraryDependencies += "org.scala-js" %% "scalajs-stubs" % "1.1.0" % Provided
name := "RIDE Compiler",
normalizedName := "lang",
description := "The RIDE smart contract language compiler",
libraryDependencies ++= Seq(
"org.scala-js" %% "scalajs-stubs" % "1.1.0" % Provided,
Dependencies.scalaLogging
)
)

lazy val `lang-js` = lang.js
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.wavesplatform.lang.utils

import org.scalajs.dom.*

trait Logging {
def trace(message: => String): Unit = println(message)
}
Loading

0 comments on commit 0aee7c1

Please sign in to comment.