mirror of
https://github.com/enso-org/enso.git
synced 2024-09-11 13:15:52 +03:00
Fix incremental compilation of runtime/test (#8975)
This commit is contained in:
parent
cf19115432
commit
5919eda753
538
build.sbt
538
build.sbt
@ -290,6 +290,8 @@ lazy val enso = (project in file("."))
|
||||
searcher,
|
||||
launcher,
|
||||
downloader,
|
||||
`runtime-integration-tests`,
|
||||
`runtime-benchmarks`,
|
||||
`runtime-parser`,
|
||||
`runtime-compiler`,
|
||||
`runtime-language-epb`,
|
||||
@ -320,6 +322,7 @@ lazy val enso = (project in file("."))
|
||||
`enso-test-java-helpers`,
|
||||
`exploratory-benchmark-java-helpers`,
|
||||
`benchmark-java-helpers`,
|
||||
`benchmarks-common`,
|
||||
`bench-processor`
|
||||
)
|
||||
.settings(Global / concurrentRestrictions += Tags.exclusive(Exclusive))
|
||||
@ -1571,7 +1574,6 @@ lazy val `runtime-test-instruments` =
|
||||
)
|
||||
|
||||
lazy val runtime = (project in file("engine/runtime"))
|
||||
.configs(Benchmark)
|
||||
.enablePlugins(JPMSPlugin)
|
||||
.settings(
|
||||
frgaalJavaCompilerSetting,
|
||||
@ -1584,39 +1586,9 @@ lazy val runtime = (project in file("engine/runtime"))
|
||||
version := ensoVersion,
|
||||
commands += WithDebugCommand.withDebug,
|
||||
inConfig(Compile)(truffleRunOptionsSettings),
|
||||
// Explicitly provide javafmt task for the custom Benchmark configuration.
|
||||
// Note that because of the custom Benchmark configuration, the `JavaFormatterPlugin`
|
||||
// is not able to register this task on its own.
|
||||
Benchmark / javafmt := {
|
||||
val streamz = streams.value
|
||||
val sD = (Benchmark / javafmt / sourceDirectories).value.toList
|
||||
val iF = (Benchmark / javafmt / includeFilter).value
|
||||
val eF = (Benchmark / javafmt / excludeFilter).value
|
||||
val cache = streamz.cacheStoreFactory
|
||||
val options = (Compile / javafmtOptions).value
|
||||
JavaFormatter(sD, iF, eF, streamz, cache, options)
|
||||
},
|
||||
Benchmark / javafmtCheck := {
|
||||
val streamz = streams.value
|
||||
val baseDir = (ThisBuild / baseDirectory).value
|
||||
val sD = (Benchmark / javafmt / sourceDirectories).value.toList
|
||||
val iF = (Benchmark / javafmt / includeFilter).value
|
||||
val eF = (Benchmark / javafmt / excludeFilter).value
|
||||
val cache = (javafmt / streams).value.cacheStoreFactory
|
||||
val options = (Compile / javafmtOptions).value
|
||||
JavaFormatter.check(baseDir, sD, iF, eF, streamz, cache, options)
|
||||
},
|
||||
Test / parallelExecution := false,
|
||||
Test / logBuffered := false,
|
||||
Test / javaOptions ++= Seq(
|
||||
"-Dtck.values=java-host,enso",
|
||||
"-Dtck.language=enso",
|
||||
"-Dtck.inlineVerifierInstrument=false",
|
||||
"-Dpolyglot.engine.AllowExperimentalOptions=true"
|
||||
),
|
||||
scalacOptions += "-Ymacro-annotations",
|
||||
scalacOptions ++= Seq("-Ypatmat-exhaust-depth", "off"),
|
||||
libraryDependencies ++= jmh ++ jaxb ++ GraalVM.langsPkgs ++ Seq(
|
||||
libraryDependencies ++= GraalVM.langsPkgs ++ Seq(
|
||||
"org.apache.commons" % "commons-lang3" % commonsLangVersion,
|
||||
"org.apache.tika" % "tika-core" % tikaVersion,
|
||||
"com.lihaoyi" %% "fansi" % fansiVersion,
|
||||
@ -1624,18 +1596,13 @@ lazy val runtime = (project in file("engine/runtime"))
|
||||
"org.graalvm.sdk" % "polyglot-tck" % graalMavenPackagesVersion % "provided",
|
||||
"org.graalvm.truffle" % "truffle-api" % graalMavenPackagesVersion % "provided",
|
||||
"org.graalvm.truffle" % "truffle-dsl-processor" % graalMavenPackagesVersion % "provided",
|
||||
"org.graalvm.truffle" % "truffle-tck" % graalMavenPackagesVersion % Test,
|
||||
"org.graalvm.truffle" % "truffle-tck-common" % graalMavenPackagesVersion % Test,
|
||||
"org.graalvm.truffle" % "truffle-tck-tests" % graalMavenPackagesVersion % Test,
|
||||
"org.netbeans.api" % "org-openide-util-lookup" % netbeansApiVersion % "provided",
|
||||
"org.scalacheck" %% "scalacheck" % scalacheckVersion % Test,
|
||||
"org.scalactic" %% "scalactic" % scalacticVersion % Test,
|
||||
"org.scalatest" %% "scalatest" % scalatestVersion % Test,
|
||||
"org.graalvm.truffle" % "truffle-api" % graalMavenPackagesVersion % Benchmark,
|
||||
"junit" % "junit" % junitVersion % Test,
|
||||
"com.github.sbt" % "junit-interface" % junitIfVersion % Test,
|
||||
"org.hamcrest" % "hamcrest-all" % hamcrestVersion % Test,
|
||||
"org.slf4j" % "slf4j-nop" % slf4jVersion % Benchmark,
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion % Test
|
||||
),
|
||||
// Add all GraalVM packages with Runtime scope - we don't need them for compilation,
|
||||
@ -1650,109 +1617,6 @@ lazy val runtime = (project in file("engine/runtime"))
|
||||
necessaryModules ++ langs ++ tools
|
||||
}
|
||||
)
|
||||
.settings(
|
||||
Test / unmanagedClasspath := (LocalProject(
|
||||
"runtime-fat-jar"
|
||||
) / Compile / exportedProducts).value,
|
||||
Test / addModules := Seq(
|
||||
(`runtime-test-instruments` / javaModuleName).value,
|
||||
(`runtime-fat-jar` / javaModuleName).value
|
||||
),
|
||||
Test / modulePath := {
|
||||
val updateReport = (Test / update).value
|
||||
val requiredModIds =
|
||||
GraalVM.modules ++ GraalVM.langsPkgs ++ GraalVM.insightPkgs ++ logbackPkg ++ Seq(
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion,
|
||||
"org.netbeans.api" % "org-openide-util-lookup" % netbeansApiVersion,
|
||||
"org.graalvm.sdk" % "polyglot-tck" % graalMavenPackagesVersion,
|
||||
"org.graalvm.truffle" % "truffle-tck" % graalMavenPackagesVersion,
|
||||
"org.graalvm.truffle" % "truffle-tck-common" % graalMavenPackagesVersion,
|
||||
"org.graalvm.truffle" % "truffle-tck-tests" % graalMavenPackagesVersion
|
||||
)
|
||||
val requiredMods = JPMSUtils.filterModulesFromUpdate(
|
||||
updateReport,
|
||||
requiredModIds,
|
||||
streams.value.log,
|
||||
shouldContainAll = true
|
||||
)
|
||||
val runtimeTestInstrumentsMod =
|
||||
(`runtime-test-instruments` / Compile / exportedProducts).value.head.data
|
||||
val runtimeMod =
|
||||
(`runtime-fat-jar` / Compile / exportedProducts).value.head.data
|
||||
requiredMods ++
|
||||
Seq(runtimeTestInstrumentsMod) ++
|
||||
Seq(runtimeMod)
|
||||
},
|
||||
Test / patchModules := {
|
||||
|
||||
/** All these modules will be in --patch-module cmdline option to java, which means that
|
||||
* for the JVM, it will appear that all the classes contained in these sbt projects are contained
|
||||
* in the `org.enso.runtime` module. In this way, we do not have to assembly the `runtime.jar`
|
||||
* fat jar.
|
||||
*/
|
||||
val modulesToPatchIntoRuntime: Seq[File] =
|
||||
(LocalProject(
|
||||
"runtime-instrument-common"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-instrument-id-execution"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-instrument-repl-debugger"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-instrument-runtime-server"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-language-epb"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-compiler"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"refactoring-utils"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-instrument-common"
|
||||
) / Test / productDirectories).value
|
||||
// Patch test-classes into the runtime module. This is standard way to deal with the
|
||||
// split package problem in unit tests. For example, Maven's surefire plugin does this.
|
||||
val testClassesDir = (Test / productDirectories).value.head
|
||||
Map(
|
||||
(`runtime-fat-jar` / javaModuleName).value -> (modulesToPatchIntoRuntime ++ Seq(
|
||||
testClassesDir
|
||||
))
|
||||
)
|
||||
},
|
||||
Test / addReads := {
|
||||
val runtimeModName = (`runtime-fat-jar` / javaModuleName).value
|
||||
val testInstrumentsModName =
|
||||
(`runtime-test-instruments` / javaModuleName).value
|
||||
Map(
|
||||
// We patched the test-classes into the runtime module. These classes access some stuff from
|
||||
// unnamed module. Thus, let's add ALL-UNNAMED.
|
||||
runtimeModName -> Seq(
|
||||
"ALL-UNNAMED",
|
||||
testInstrumentsModName,
|
||||
"truffle.tck.tests",
|
||||
"org.openide.util.lookup.RELEASE180"
|
||||
),
|
||||
testInstrumentsModName -> Seq(runtimeModName)
|
||||
)
|
||||
},
|
||||
Test / javaOptions ++= testLogProviderOptions
|
||||
)
|
||||
.settings(
|
||||
Test / fork := true,
|
||||
Test / envVars ++= distributionEnvironmentOverrides ++ Map(
|
||||
"ENSO_TEST_DISABLE_IR_CACHE" -> "false",
|
||||
"ENSO_EDITION_PATH" -> file("distribution/editions").getCanonicalPath
|
||||
),
|
||||
Test / compile := {
|
||||
(LocalProject("runtime-instrument-common") / Test / compile).value
|
||||
(Test / compile).value
|
||||
}
|
||||
)
|
||||
.settings(
|
||||
(Compile / javacOptions) ++= Seq(
|
||||
"-s",
|
||||
@ -1778,50 +1642,6 @@ lazy val runtime = (project in file("engine/runtime"))
|
||||
.dependsOn(`std-aws` / Compile / packageBin)
|
||||
.value
|
||||
)
|
||||
/** Benchmark settings */
|
||||
.settings(
|
||||
inConfig(Benchmark)(Defaults.testSettings),
|
||||
Benchmark / javacOptions --= Seq(
|
||||
"-source",
|
||||
frgaalSourceLevel,
|
||||
"--enable-preview"
|
||||
),
|
||||
(Benchmark / javaOptions) :=
|
||||
(LocalProject("std-benchmarks") / Benchmark / run / javaOptions).value,
|
||||
(Benchmark / javaOptions) ++= benchOnlyOptions,
|
||||
Benchmark / fork := true,
|
||||
Benchmark / parallelExecution := false,
|
||||
// This ensures that the full class-path of runtime-fat-jar is put on
|
||||
// class-path of the Java compiler (and thus the benchmark annotation processor).
|
||||
(Benchmark / compile / unmanagedClasspath) ++=
|
||||
(LocalProject(
|
||||
"runtime-fat-jar"
|
||||
) / Compile / fullClasspath).value,
|
||||
bench := (Benchmark / test)
|
||||
.tag(Exclusive)
|
||||
.dependsOn(
|
||||
// runtime.jar fat jar needs to be assembled as it is used in the
|
||||
// benchmarks. This dependency is here so that `runtime/bench` works
|
||||
// after clean build.
|
||||
LocalProject("runtime-fat-jar") / assembly
|
||||
)
|
||||
.value,
|
||||
(Benchmark / testOnly) := (Benchmark / testOnly)
|
||||
.dependsOn(
|
||||
LocalProject("runtime-fat-jar") / assembly
|
||||
)
|
||||
.evaluated,
|
||||
benchOnly := Def.inputTaskDyn {
|
||||
import complete.Parsers.spaceDelimited
|
||||
val name = spaceDelimited("<name>").parsed match {
|
||||
case List(name) => name
|
||||
case _ => throw new IllegalArgumentException("Expected one argument.")
|
||||
}
|
||||
Def.task {
|
||||
(Benchmark / testOnly).toTask(" -- -z " + name).value
|
||||
}
|
||||
}.evaluated
|
||||
)
|
||||
.dependsOn(`common-polyglot-core-utils`)
|
||||
.dependsOn(`edition-updater`)
|
||||
.dependsOn(`interpreter-dsl`)
|
||||
@ -1833,8 +1653,238 @@ lazy val runtime = (project in file("engine/runtime"))
|
||||
.dependsOn(`runtime-compiler`)
|
||||
.dependsOn(`connected-lock-manager`)
|
||||
.dependsOn(testkit % Test)
|
||||
.dependsOn(`logging-service-logback` % "test->test")
|
||||
.dependsOn(`runtime-test-instruments` % "test->compile")
|
||||
|
||||
/** A project holding all the runtime integration tests. These tests require, among other things,
|
||||
* the `org.enso.runtime` JPMS module, so it is easier to keep them in a separate project.
|
||||
* For standard unit tests, use `runtime/Test`.
|
||||
*/
|
||||
lazy val `runtime-integration-tests` =
|
||||
(project in file("engine/runtime-integration-tests"))
|
||||
.enablePlugins(JPMSPlugin)
|
||||
.settings(
|
||||
frgaalJavaCompilerSetting,
|
||||
Compile / logManager :=
|
||||
sbt.internal.util.CustomLogManager.excludeMsg(
|
||||
"Could not determine source for class ",
|
||||
Level.Warn
|
||||
),
|
||||
commands += WithDebugCommand.withDebug,
|
||||
libraryDependencies ++= GraalVM.modules ++ GraalVM.langsPkgs ++ GraalVM.insightPkgs ++ logbackPkg ++ Seq(
|
||||
"org.graalvm.polyglot" % "polyglot" % graalMavenPackagesVersion % "provided",
|
||||
"org.graalvm.sdk" % "polyglot-tck" % graalMavenPackagesVersion % "provided",
|
||||
"org.graalvm.truffle" % "truffle-api" % graalMavenPackagesVersion % "provided",
|
||||
"org.graalvm.truffle" % "truffle-dsl-processor" % graalMavenPackagesVersion % "provided",
|
||||
"org.graalvm.truffle" % "truffle-tck" % graalMavenPackagesVersion % Test,
|
||||
"org.graalvm.truffle" % "truffle-tck-common" % graalMavenPackagesVersion % Test,
|
||||
"org.graalvm.truffle" % "truffle-tck-tests" % graalMavenPackagesVersion % Test,
|
||||
"org.scalacheck" %% "scalacheck" % scalacheckVersion % Test,
|
||||
"org.scalactic" %% "scalactic" % scalacticVersion % Test,
|
||||
"org.scalatest" %% "scalatest" % scalatestVersion % Test,
|
||||
"junit" % "junit" % junitVersion % Test,
|
||||
"com.github.sbt" % "junit-interface" % junitIfVersion % Test,
|
||||
"org.hamcrest" % "hamcrest-all" % hamcrestVersion % Test,
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion % Test
|
||||
),
|
||||
Test / javacOptions ++= Seq(
|
||||
"-s",
|
||||
(Compile / sourceManaged).value.getAbsolutePath,
|
||||
"-Xlint:unchecked"
|
||||
),
|
||||
Test / compile := (Test / compile)
|
||||
.dependsOn(Def.task { (Compile / sourceManaged).value.mkdirs })
|
||||
.dependsOn(`runtime-fat-jar` / Compile / compileModuleInfo)
|
||||
.value,
|
||||
Test / fork := true,
|
||||
Test / parallelExecution := false,
|
||||
Test / logBuffered := false,
|
||||
Test / envVars ++= distributionEnvironmentOverrides ++ Map(
|
||||
"ENSO_TEST_DISABLE_IR_CACHE" -> "false",
|
||||
"ENSO_EDITION_PATH" -> file("distribution/editions").getCanonicalPath
|
||||
),
|
||||
inConfig(Test)(truffleRunOptionsSettings),
|
||||
Test / javaOptions ++= Seq(
|
||||
"-Dtck.values=java-host,enso",
|
||||
"-Dtck.language=enso",
|
||||
"-Dtck.inlineVerifierInstrument=false",
|
||||
"-Dpolyglot.engine.AllowExperimentalOptions=true"
|
||||
),
|
||||
Test / javaOptions ++= testLogProviderOptions,
|
||||
Test / addModules := Seq(
|
||||
(`runtime-test-instruments` / javaModuleName).value,
|
||||
(`runtime-fat-jar` / javaModuleName).value
|
||||
),
|
||||
Test / modulePath := {
|
||||
val updateReport = (Test / update).value
|
||||
val requiredModIds =
|
||||
GraalVM.modules ++ GraalVM.langsPkgs ++ GraalVM.insightPkgs ++ logbackPkg ++ Seq(
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion,
|
||||
"org.netbeans.api" % "org-openide-util-lookup" % netbeansApiVersion,
|
||||
"org.graalvm.sdk" % "polyglot-tck" % graalMavenPackagesVersion,
|
||||
"org.graalvm.truffle" % "truffle-tck" % graalMavenPackagesVersion,
|
||||
"org.graalvm.truffle" % "truffle-tck-common" % graalMavenPackagesVersion,
|
||||
"org.graalvm.truffle" % "truffle-tck-tests" % graalMavenPackagesVersion
|
||||
)
|
||||
val requiredMods = JPMSUtils.filterModulesFromUpdate(
|
||||
updateReport,
|
||||
requiredModIds,
|
||||
streams.value.log,
|
||||
shouldContainAll = true
|
||||
)
|
||||
val runtimeTestInstrumentsMod =
|
||||
(`runtime-test-instruments` / Compile / exportedProducts).value.head.data
|
||||
val runtimeMod =
|
||||
(`runtime-fat-jar` / Compile / exportedProducts).value.head.data
|
||||
requiredMods ++
|
||||
Seq(runtimeTestInstrumentsMod) ++
|
||||
Seq(runtimeMod)
|
||||
},
|
||||
Test / patchModules := {
|
||||
|
||||
/** All these modules will be in --patch-module cmdline option to java, which means that
|
||||
* for the JVM, it will appear that all the classes contained in these sbt projects are contained
|
||||
* in the `org.enso.runtime` module. In this way, we do not have to assembly the `runtime.jar`
|
||||
* fat jar.
|
||||
*/
|
||||
val modulesToPatchIntoRuntime: Seq[File] =
|
||||
(LocalProject(
|
||||
"runtime-instrument-common"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-instrument-id-execution"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-instrument-repl-debugger"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-instrument-runtime-server"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-language-epb"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-compiler"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"refactoring-utils"
|
||||
) / Compile / productDirectories).value ++
|
||||
(LocalProject(
|
||||
"runtime-instrument-common"
|
||||
) / Test / productDirectories).value
|
||||
// Patch test-classes into the runtime module. This is standard way to deal with the
|
||||
// split package problem in unit tests. For example, Maven's surefire plugin does this.
|
||||
val testClassesDir = (Test / productDirectories).value.head
|
||||
Map(
|
||||
(`runtime-fat-jar` / javaModuleName).value -> (modulesToPatchIntoRuntime ++ Seq(
|
||||
testClassesDir
|
||||
))
|
||||
)
|
||||
},
|
||||
Test / addReads := {
|
||||
val runtimeModName = (`runtime-fat-jar` / javaModuleName).value
|
||||
val testInstrumentsModName =
|
||||
(`runtime-test-instruments` / javaModuleName).value
|
||||
Map(
|
||||
// We patched the test-classes into the runtime module. These classes access some stuff from
|
||||
// unnamed module. Thus, let's add ALL-UNNAMED.
|
||||
runtimeModName -> Seq(
|
||||
"ALL-UNNAMED",
|
||||
testInstrumentsModName,
|
||||
"truffle.tck.tests",
|
||||
"org.openide.util.lookup.RELEASE180"
|
||||
),
|
||||
testInstrumentsModName -> Seq(runtimeModName)
|
||||
)
|
||||
}
|
||||
)
|
||||
.dependsOn(`runtime-fat-jar`)
|
||||
.dependsOn(`runtime-test-instruments`)
|
||||
.dependsOn(`logging-service-logback` % "test->test")
|
||||
.dependsOn(testkit % Test)
|
||||
|
||||
/** A project that holds only benchmarks for `runtime`. Unlike `runtime-integration-tests`, its execution requires
|
||||
* the whole `runtime-fat-jar` assembly, as we want to be as close to the enso distribution as possible.
|
||||
*/
|
||||
lazy val `runtime-benchmarks` =
|
||||
(project in file("engine/runtime-benchmarks"))
|
||||
.enablePlugins(JPMSPlugin)
|
||||
.settings(
|
||||
frgaalJavaCompilerSetting,
|
||||
// Note that withDebug command only makes sense if you use `@Fork(0)` in your benchmarks.
|
||||
commands += WithDebugCommand.withDebug,
|
||||
libraryDependencies ++= GraalVM.modules ++ GraalVM.langsPkgs ++ GraalVM.toolsPkgs ++ Seq(
|
||||
"org.openjdk.jmh" % "jmh-core" % jmhVersion,
|
||||
"org.openjdk.jmh" % "jmh-generator-annprocess" % jmhVersion,
|
||||
"jakarta.xml.bind" % "jakarta.xml.bind-api" % jaxbVersion,
|
||||
"com.sun.xml.bind" % "jaxb-impl" % jaxbVersion,
|
||||
"org.graalvm.truffle" % "truffle-api" % graalMavenPackagesVersion,
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion,
|
||||
"org.slf4j" % "slf4j-nop" % slf4jVersion
|
||||
),
|
||||
mainClass :=
|
||||
Some("org.enso.interpreter.bench.benchmarks.RuntimeBenchmarksRunner"),
|
||||
Compile / logManager :=
|
||||
sbt.internal.util.CustomLogManager.excludeMsg(
|
||||
"Could not determine source for class ",
|
||||
Level.Warn
|
||||
),
|
||||
javacOptions --= Seq(
|
||||
"-source",
|
||||
frgaalSourceLevel,
|
||||
"--enable-preview"
|
||||
),
|
||||
parallelExecution := false,
|
||||
modulePath := {
|
||||
val requiredModIds = GraalVM.modules ++ GraalVM.langsPkgs ++ Seq(
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion,
|
||||
"org.slf4j" % "slf4j-nop" % slf4jVersion
|
||||
)
|
||||
val requiredMods = JPMSUtils.filterModulesFromUpdate(
|
||||
(Compile / update).value,
|
||||
requiredModIds,
|
||||
streams.value.log,
|
||||
shouldContainAll = true
|
||||
)
|
||||
val runtimeMod =
|
||||
(`runtime-fat-jar` / assembly / assemblyOutputPath).value
|
||||
requiredMods ++ Seq(runtimeMod)
|
||||
},
|
||||
addModules := {
|
||||
val runtimeModuleName = (`runtime-fat-jar` / javaModuleName).value
|
||||
Seq(runtimeModuleName)
|
||||
},
|
||||
addExports := {
|
||||
Map("org.slf4j.nop/org.slf4j.nop" -> Seq("org.slf4j"))
|
||||
},
|
||||
javaOptions ++= {
|
||||
Seq(
|
||||
// To enable logging in benchmarks, add ch.qos.logback module on the modulePath
|
||||
"-Dslf4j.provider=org.slf4j.nop.NOPServiceProvider"
|
||||
)
|
||||
},
|
||||
javaOptions ++= benchOnlyOptions,
|
||||
run / fork := true,
|
||||
run / connectInput := true,
|
||||
bench := Def
|
||||
.task {
|
||||
(Compile / run).toTask("").tag(Exclusive).value
|
||||
}
|
||||
.dependsOn(
|
||||
buildEngineDistribution
|
||||
)
|
||||
.value,
|
||||
benchOnly := Def.inputTaskDyn {
|
||||
import complete.Parsers.spaceDelimited
|
||||
val name = spaceDelimited("<name>").parsed match {
|
||||
case List(name) => name
|
||||
case _ => throw new IllegalArgumentException("Expected one argument.")
|
||||
}
|
||||
Def.task {
|
||||
(Compile / run).toTask(" " + name).value
|
||||
}
|
||||
}.evaluated
|
||||
)
|
||||
.dependsOn(`runtime-fat-jar`)
|
||||
.dependsOn(`benchmarks-common`)
|
||||
|
||||
lazy val `runtime-parser` =
|
||||
(project in file("engine/runtime-parser"))
|
||||
@ -1895,7 +1945,7 @@ lazy val `runtime-instrument-common` =
|
||||
bench := (Benchmark / test).tag(Exclusive).value,
|
||||
Benchmark / parallelExecution := false,
|
||||
(Benchmark / javaOptions) :=
|
||||
(LocalProject("std-benchmarks") / Benchmark / run / javaOptions).value,
|
||||
(LocalProject("std-benchmarks") / Compile / javaOptions).value,
|
||||
Test / fork := true,
|
||||
Test / envVars ++= distributionEnvironmentOverrides ++ Map(
|
||||
"ENSO_TEST_DISABLE_IR_CACHE" -> "false"
|
||||
@ -2258,6 +2308,19 @@ lazy val `distribution-manager` = project
|
||||
.dependsOn(pkg)
|
||||
.dependsOn(`logging-utils`)
|
||||
|
||||
lazy val `benchmarks-common` =
|
||||
(project in file("lib/java/benchmarks-common"))
|
||||
.settings(
|
||||
frgaalJavaCompilerSetting,
|
||||
libraryDependencies ++= GraalVM.modules ++ Seq(
|
||||
"org.openjdk.jmh" % "jmh-core" % jmhVersion,
|
||||
"org.openjdk.jmh" % "jmh-generator-annprocess" % jmhVersion,
|
||||
"jakarta.xml.bind" % "jakarta.xml.bind-api" % jaxbVersion,
|
||||
"com.sun.xml.bind" % "jaxb-impl" % jaxbVersion
|
||||
)
|
||||
)
|
||||
.dependsOn(`polyglot-api`)
|
||||
|
||||
lazy val `bench-processor` = (project in file("lib/scala/bench-processor"))
|
||||
.settings(
|
||||
frgaalJavaCompilerSetting,
|
||||
@ -2292,28 +2355,21 @@ lazy val `bench-processor` = (project in file("lib/scala/bench-processor"))
|
||||
(Test / unmanagedClasspath) :=
|
||||
(LocalProject("runtime-fat-jar") / Compile / fullClasspath).value
|
||||
)
|
||||
.dependsOn(`benchmarks-common`)
|
||||
.dependsOn(`polyglot-api`)
|
||||
.dependsOn(runtime)
|
||||
|
||||
lazy val `std-benchmarks` = (project in file("std-bits/benchmarks"))
|
||||
.enablePlugins(JPMSPlugin)
|
||||
.settings(
|
||||
frgaalJavaCompilerSetting,
|
||||
libraryDependencies ++= jmh ++ Seq(
|
||||
"org.openjdk.jmh" % "jmh-core" % jmhVersion % Benchmark,
|
||||
"org.openjdk.jmh" % "jmh-generator-annprocess" % jmhVersion % Benchmark,
|
||||
"org.graalvm.polyglot" % "polyglot" % graalMavenPackagesVersion % Benchmark,
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion % Benchmark,
|
||||
"org.slf4j" % "slf4j-nop" % slf4jVersion % Benchmark
|
||||
libraryDependencies ++= GraalVM.modules ++ GraalVM.langsPkgs ++ Seq(
|
||||
"org.openjdk.jmh" % "jmh-core" % jmhVersion,
|
||||
"org.openjdk.jmh" % "jmh-generator-annprocess" % jmhVersion,
|
||||
"org.graalvm.polyglot" % "polyglot" % graalMavenPackagesVersion,
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion,
|
||||
"org.slf4j" % "slf4j-nop" % slf4jVersion
|
||||
),
|
||||
// Add all GraalVM packages with Benchmark scope - we don't need them for compilation,
|
||||
// just provide them for benchmarks (in module-path).
|
||||
libraryDependencies ++= {
|
||||
val necessaryModules =
|
||||
GraalVM.modules.map(_.withConfigurations(Some(Benchmark.name)))
|
||||
val langs =
|
||||
GraalVM.langsPkgs.map(_.withConfigurations(Some(Benchmark.name)))
|
||||
necessaryModules ++ langs
|
||||
},
|
||||
commands += WithDebugCommand.withDebug,
|
||||
(Compile / logManager) :=
|
||||
sbt.internal.util.CustomLogManager.excludeMsg(
|
||||
@ -2321,67 +2377,56 @@ lazy val `std-benchmarks` = (project in file("std-bits/benchmarks"))
|
||||
Level.Warn
|
||||
)
|
||||
)
|
||||
.configs(Benchmark)
|
||||
.settings(
|
||||
inConfig(Benchmark)(Defaults.testSettings)
|
||||
)
|
||||
.settings(
|
||||
(Benchmark / parallelExecution) := false,
|
||||
(Benchmark / run / fork) := true,
|
||||
(Benchmark / run / connectInput) := true,
|
||||
// This ensures that the full class-path of runtime-fat-jar is put on
|
||||
// class-path of the Java compiler (and thus the benchmark annotation processor).
|
||||
(Benchmark / compile / unmanagedClasspath) ++=
|
||||
(LocalProject(
|
||||
"runtime-fat-jar"
|
||||
) / Compile / fullClasspath).value,
|
||||
(Benchmark / compile / javacOptions) ++= Seq(
|
||||
parallelExecution := false,
|
||||
run / fork := true,
|
||||
run / connectInput := true,
|
||||
mainClass :=
|
||||
(LocalProject("bench-processor") / mainClass).value,
|
||||
Compile / compile := (Compile / compile)
|
||||
.dependsOn(`runtime-fat-jar` / assembly)
|
||||
.value,
|
||||
Compile / javacOptions ++= Seq(
|
||||
"-s",
|
||||
(Benchmark / sourceManaged).value.getAbsolutePath,
|
||||
(Compile / sourceManaged).value.getAbsolutePath,
|
||||
"-Xlint:unchecked",
|
||||
"-J-Dpolyglotimpl.DisableClassPathIsolation=true",
|
||||
"-J-Dpolyglot.engine.WarnInterpreterOnly=false"
|
||||
),
|
||||
(Benchmark / run / javaOptions) ++= {
|
||||
val requiredModules = GraalVM.modules ++ GraalVM.langsPkgs ++ Seq(
|
||||
modulePath := {
|
||||
val requiredModIds = GraalVM.modules ++ GraalVM.langsPkgs ++ Seq(
|
||||
"org.slf4j" % "slf4j-api" % slf4jVersion,
|
||||
"org.slf4j" % "slf4j-nop" % slf4jVersion
|
||||
)
|
||||
val requiredModulesCp = JPMSUtils.filterModulesFromClasspath(
|
||||
(Benchmark / fullClasspath).value,
|
||||
requiredModules,
|
||||
val requiredMods = JPMSUtils.filterModulesFromUpdate(
|
||||
(Compile / update).value,
|
||||
requiredModIds,
|
||||
streams.value.log,
|
||||
shouldContainAll = true
|
||||
)
|
||||
val requiredModulesPaths = requiredModulesCp
|
||||
.map(_.data.getAbsolutePath)
|
||||
val runtimeJar =
|
||||
(LocalProject(
|
||||
"runtime-fat-jar"
|
||||
) / assembly / assemblyOutputPath).value.getAbsolutePath
|
||||
val allModulePaths = requiredModulesPaths ++ Seq(runtimeJar)
|
||||
val runtimeModuleName =
|
||||
(LocalProject(
|
||||
"runtime-fat-jar"
|
||||
) / javaModuleName).value
|
||||
val runtimeMod =
|
||||
(`runtime-fat-jar` / assembly / assemblyOutputPath).value
|
||||
requiredMods ++ Seq(runtimeMod)
|
||||
},
|
||||
addModules := {
|
||||
val runtimeModuleName = (`runtime-fat-jar` / javaModuleName).value
|
||||
Seq(runtimeModuleName)
|
||||
},
|
||||
addExports := {
|
||||
Map("org.slf4j.nop/org.slf4j.nop" -> Seq("org.slf4j"))
|
||||
},
|
||||
javaOptions ++= {
|
||||
Seq(
|
||||
// To enable logging in benchmarks, add ch.qos.logback module on the modulePath
|
||||
"-Dslf4j.provider=org.slf4j.nop.NOPServiceProvider",
|
||||
"--module-path",
|
||||
allModulePaths.mkString(File.pathSeparator),
|
||||
"--add-modules",
|
||||
runtimeModuleName,
|
||||
"--add-exports",
|
||||
"org.slf4j.nop/org.slf4j.nop=org.slf4j"
|
||||
"-Dslf4j.provider=org.slf4j.nop.NOPServiceProvider"
|
||||
)
|
||||
},
|
||||
(Benchmark / run / mainClass) :=
|
||||
(LocalProject("bench-processor") / mainClass).value
|
||||
javaOptions ++= benchOnlyOptions
|
||||
)
|
||||
.settings(
|
||||
bench := Def
|
||||
.task {
|
||||
(Benchmark / run).toTask("").tag(Exclusive).value
|
||||
(Compile / run).toTask("").tag(Exclusive).value
|
||||
}
|
||||
.dependsOn(
|
||||
buildEngineDistribution
|
||||
@ -2394,12 +2439,13 @@ lazy val `std-benchmarks` = (project in file("std-bits/benchmarks"))
|
||||
case _ => throw new IllegalArgumentException("Expected one argument.")
|
||||
}
|
||||
Def.task {
|
||||
(Benchmark / run).toTask(" " + name).value
|
||||
(Compile / run).toTask(" " + name).value
|
||||
}
|
||||
}.evaluated
|
||||
)
|
||||
.dependsOn(`bench-processor` % Benchmark)
|
||||
.dependsOn(runtime % Benchmark)
|
||||
.dependsOn(`bench-processor`)
|
||||
.dependsOn(`runtime-fat-jar`)
|
||||
.dependsOn(`std-table`)
|
||||
|
||||
lazy val editions = project
|
||||
.in(file("lib/scala/editions"))
|
||||
|
@ -91,6 +91,7 @@
|
||||
Factorial.enso:
|
||||
runtime/:
|
||||
target/:
|
||||
runtime-benchmarks/:
|
||||
bench-report.xml:
|
||||
lib/:
|
||||
rust/:
|
||||
|
@ -105,7 +105,7 @@ impl Benchmarks {
|
||||
pub fn sbt_task(self) -> Option<&'static str> {
|
||||
match self {
|
||||
Benchmarks::All => Some("bench"),
|
||||
Benchmarks::Runtime => Some("runtime/bench"),
|
||||
Benchmarks::Runtime => Some("runtime-benchmarks/bench"),
|
||||
Benchmarks::Enso => None,
|
||||
Benchmarks::EnsoJMH => Some("std-benchmarks/bench"),
|
||||
}
|
||||
|
@ -448,7 +448,7 @@ impl RunContext {
|
||||
} else {
|
||||
if self.config.build_benchmarks {
|
||||
// Check Runtime Benchmark Compilation
|
||||
sbt.call_arg("runtime/Benchmark/compile").await?;
|
||||
sbt.call_arg("runtime-benchmarks/compile").await?;
|
||||
|
||||
// Check Language Server Benchmark Compilation
|
||||
sbt.call_arg("language-server/Benchmark/compile").await?;
|
||||
@ -478,8 +478,12 @@ impl RunContext {
|
||||
for bench in &self.config.execute_benchmarks {
|
||||
match bench {
|
||||
Benchmarks::Runtime => {
|
||||
let runtime_bench_report =
|
||||
&self.paths.repo_root.engine.runtime.bench_report_xml;
|
||||
let runtime_bench_report = &self
|
||||
.paths
|
||||
.repo_root
|
||||
.engine
|
||||
.join("runtime-benchmarks")
|
||||
.join("bench-report.xml");
|
||||
if runtime_bench_report.exists() {
|
||||
ide_ci::actions::artifacts::upload_single_file(
|
||||
runtime_bench_report,
|
||||
|
@ -13,26 +13,38 @@ To track the performance of the engine, we use
|
||||
benchmarks:
|
||||
|
||||
- [micro benchmarks](#engine-jmh-microbenchmarks) located directly in the
|
||||
`runtime` SBT project. These benchmarks are written in Java, and are used to
|
||||
measure the performance of specific parts of the engine.
|
||||
`runtime-benchmarks` SBT project. These benchmarks are written in Java, and
|
||||
are used to measure the performance of specific parts of the engine.
|
||||
- [standard library benchmarks](#standard-library-benchmarks) located in the
|
||||
`test/Benchmarks` Enso project. These benchmarks are entirelly written in
|
||||
Enso, along with the harness code.
|
||||
`test/Benchmarks` Enso project. These benchmarks are entirely written in Enso,
|
||||
along with the harness code.
|
||||
|
||||
## Engine JMH microbenchmarks
|
||||
|
||||
These benchmarks are written in Java and are used to measure the performance of
|
||||
specific parts of the engine. The sources are located in the `runtime` SBT
|
||||
project, under `src/bench` source directory.
|
||||
specific parts of the engine. The sources are located in the
|
||||
`runtime-benchmarks` SBT project, under `engine/runtime-benchmarks` directory.
|
||||
|
||||
### Running the benchmarks
|
||||
|
||||
To run the benchmarks, use `bench` or `benchOnly` command - `bench` runs all the
|
||||
benchmarks and `benchOnly` runs only one benchmark specified with the fully
|
||||
qualified name. The parameters for these benchmarks are hard-coded inside the
|
||||
JMH annotations in the source files. In order to change, e.g., the number of
|
||||
measurement iterations, you need to modify the parameter to the `@Measurement`
|
||||
annotation.
|
||||
To run the benchmarks, use `bench` or `benchOnly` command in the
|
||||
`runtime-benchmarks` project - `bench` runs all the benchmarks and `benchOnly`
|
||||
runs only one benchmark specified with the fully qualified name. The
|
||||
aforementioned commands are mere shortcuts to the
|
||||
[standard JMH launcher](https://github.com/openjdk/jmh/blob/master/jmh-core/src/main/java/org/openjdk/jmh/Main.java).
|
||||
To get the full power of the JMH launcher, invoke simply `run` with cmdline
|
||||
options passed to the launcher. For the full options summary, see the
|
||||
[JMH source code](https://github.com/openjdk/jmh/blob/master/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java),
|
||||
or invoke `run -h`.
|
||||
|
||||
You can change the parameters to the benchmarks either by modifying the
|
||||
annotations directly in the source code, or by passing the parameters to the JMH
|
||||
runner. For example, to run the benchmarks with 3 warmup iterations and 2
|
||||
measurement iterations, use:
|
||||
|
||||
```
|
||||
sbt:runtime-benchmarks> run -w 3 -i 2 <bench-name>
|
||||
```
|
||||
|
||||
### Debugging the benchmarks
|
||||
|
||||
@ -94,12 +106,12 @@ the full options summary, either see the
|
||||
or run the launcher with `-h` option.
|
||||
|
||||
The `std-benchmarks` SBT project supports `bench` and `benchOnly` commands, that
|
||||
work the same as in the `runtime` project, with the exception that the benchmark
|
||||
name does not have to be specified as a fully qualified name, but as a regular
|
||||
expression. To access the full flexibility of the JMH launcher, run it via
|
||||
`Bench/run` - for example, to see the help message: `Bench/run -h`. For example,
|
||||
you can run all the benchmarks that have "New_Vector" in their name with just 3
|
||||
seconds for warmup iterations and 2 measurement iterations with
|
||||
work the same as in the `runtime-benchmarks` project, with the exception that
|
||||
the benchmark name does not have to be specified as a fully qualified name, but
|
||||
as a regular expression. To access the full flexibility of the JMH launcher, run
|
||||
it via `Bench/run` - for example, to see the help message: `Bench/run -h`. For
|
||||
example, you can run all the benchmarks that have "New_Vector" in their name
|
||||
with just 3 seconds for warmup iterations and 2 measurement iterations with
|
||||
`Bench/run -w 3 -i 2 New_Vector`.
|
||||
|
||||
Whenever you add or delete any benchmarks from `test/Benchmarks` project, the
|
||||
|
@ -0,0 +1,10 @@
|
||||
package org.enso.interpreter.bench.benchmarks;
|
||||
|
||||
import org.enso.interpreter.bench.BenchmarksRunner;
|
||||
import org.openjdk.jmh.runner.RunnerException;
|
||||
|
||||
public class RuntimeBenchmarksRunner {
|
||||
public static void main(String[] args) throws RunnerException {
|
||||
BenchmarksRunner.run(args);
|
||||
}
|
||||
}
|
@ -0,0 +1,285 @@
|
||||
package org.enso.interpreter.bench.benchmarks.semantic;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.enso.interpreter.bench.Utils;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Value;
|
||||
import org.graalvm.polyglot.io.IOAccess;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.infra.BenchmarkParams;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Fork(1)
|
||||
@Warmup(iterations = 5)
|
||||
@Measurement(iterations = 5)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
public class AtomBenchmarks {
|
||||
|
||||
private static final Long MILLION = 1_000_000L;
|
||||
private static final String MILLION_ELEMENT_LIST =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
main =
|
||||
generator fn acc i end = if i == end then acc else @Tail_Call generator fn (fn acc i) i+1 end
|
||||
res = generator (acc -> x -> List.Cons x acc) List.Nil 1 $million
|
||||
res
|
||||
"""
|
||||
.replace("$million", MILLION.toString());
|
||||
|
||||
private static final String GENERATE_LIST_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
main = length ->
|
||||
generator = acc -> i -> if i == 0 then acc else @Tail_Call generator (List.Cons i acc) (i - 1)
|
||||
|
||||
res = generator List.Nil length
|
||||
res
|
||||
""";
|
||||
private static final String GENERATE_LIST_QUALIFIED_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
main = length ->
|
||||
generator = acc -> i -> if i == 0 then acc else @Tail_Call generator (List.Cons i acc) (i - 1)
|
||||
|
||||
res = generator List.Nil length
|
||||
res
|
||||
""";
|
||||
private static final String REVERSE_LIST_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
main = list ->
|
||||
reverser = acc -> list -> case list of
|
||||
List.Cons h t -> @Tail_Call reverser (List.Cons h acc) t
|
||||
List.Nil -> acc
|
||||
|
||||
res = reverser List.Nil list
|
||||
res
|
||||
""";
|
||||
private static final String REVERSE_LIST_METHODS_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
List.rev self acc = case self of
|
||||
List.Cons h t -> @Tail_Call t.rev (List.Cons h acc)
|
||||
_ -> acc
|
||||
|
||||
main = list ->
|
||||
res = list.rev List.Nil
|
||||
res
|
||||
""";
|
||||
private static final String SUM_LIST_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
main = list ->
|
||||
summator = acc -> list -> case list of
|
||||
List.Cons h t -> @Tail_Call summator acc+h t
|
||||
List.Nil -> acc
|
||||
|
||||
res = summator 0 list
|
||||
res
|
||||
""";
|
||||
private static final String SUM_LIST_LEFT_FOLD_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
main = list ->
|
||||
fold = f -> acc -> list -> case list of
|
||||
List.Cons h t -> @Tail_Call fold f (f acc h) t
|
||||
_ -> acc
|
||||
|
||||
res = fold (x -> y -> x + y) 0 list
|
||||
res
|
||||
""";
|
||||
private static final String SUM_LIST_FALLBACK_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
main = list ->
|
||||
summator = acc -> list -> case list of
|
||||
List.Cons h t -> @Tail_Call summator acc+h t
|
||||
_ -> acc
|
||||
|
||||
res = summator 0 list
|
||||
res
|
||||
""";
|
||||
private static final String SUM_LIST_METHODS_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
List.sum self acc = case self of
|
||||
List.Cons h t -> @Tail_Call t.sum h+acc
|
||||
_ -> acc
|
||||
|
||||
main = list ->
|
||||
res = list.sum 0
|
||||
res
|
||||
""";
|
||||
private static final String MAP_REVERSE_LIST_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
List.mapReverse self f acc = case self of
|
||||
List.Cons h t -> @Tail_Call t.mapReverse f (List.Cons (f h) acc)
|
||||
_ -> acc
|
||||
|
||||
main = list ->
|
||||
res = list.mapReverse (x -> x + 1) List.Nil
|
||||
res
|
||||
""";
|
||||
private static final String MAP_REVERSE_LIST_CURRY_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.List.List
|
||||
import Standard.Base.Data.Numbers
|
||||
|
||||
List.mapReverse self f acc = case self of
|
||||
List.Cons h t -> @Tail_Call t.mapReverse f (List.Cons (f h) acc)
|
||||
_ -> acc
|
||||
|
||||
main = list ->
|
||||
adder = x -> y -> x + y
|
||||
res = list.mapReverse (adder 1) List.Nil
|
||||
res
|
||||
""";
|
||||
|
||||
private Context context;
|
||||
private Value millionElementsList;
|
||||
private Value generateList;
|
||||
private Value generateListQualified;
|
||||
private Value reverseList;
|
||||
private Value reverseListMethods;
|
||||
private Value sumList;
|
||||
private Value sumListLeftFold;
|
||||
private Value sumListFallback;
|
||||
private Value sumListMethods;
|
||||
private Value mapReverseList;
|
||||
private Value mapReverseListCurry;
|
||||
|
||||
@Setup
|
||||
public void initializeBenchmarks(BenchmarkParams params) {
|
||||
this.context =
|
||||
Context.newBuilder()
|
||||
.allowExperimentalOptions(true)
|
||||
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
|
||||
.logHandler(System.err)
|
||||
.allowIO(IOAccess.ALL)
|
||||
.allowAllAccess(true)
|
||||
.option(
|
||||
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
|
||||
Paths.get("../../distribution/component").toFile().getAbsolutePath())
|
||||
.build();
|
||||
|
||||
var millionElemListMethod = Utils.getMainMethod(context, MILLION_ELEMENT_LIST);
|
||||
this.millionElementsList = millionElemListMethod.execute();
|
||||
this.generateList = Utils.getMainMethod(context, GENERATE_LIST_CODE);
|
||||
this.generateListQualified = Utils.getMainMethod(context, GENERATE_LIST_QUALIFIED_CODE);
|
||||
this.reverseList = Utils.getMainMethod(context, REVERSE_LIST_CODE);
|
||||
this.reverseListMethods = Utils.getMainMethod(context, REVERSE_LIST_METHODS_CODE);
|
||||
this.sumList = Utils.getMainMethod(context, SUM_LIST_CODE);
|
||||
this.sumListLeftFold = Utils.getMainMethod(context, SUM_LIST_LEFT_FOLD_CODE);
|
||||
this.sumListFallback = Utils.getMainMethod(context, SUM_LIST_FALLBACK_CODE);
|
||||
this.sumListMethods = Utils.getMainMethod(context, SUM_LIST_METHODS_CODE);
|
||||
this.mapReverseList = Utils.getMainMethod(context, MAP_REVERSE_LIST_CODE);
|
||||
this.mapReverseListCurry = Utils.getMainMethod(context, MAP_REVERSE_LIST_CURRY_CODE);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchGenerateList(Blackhole bh) {
|
||||
var res = generateList.execute(MILLION);
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchGenerateListQualified(Blackhole bh) {
|
||||
var res = generateListQualified.execute(MILLION);
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchReverseList(Blackhole bh) {
|
||||
var reversedList = reverseList.execute(millionElementsList);
|
||||
bh.consume(reversedList);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchReverseListMethods(Blackhole bh) {
|
||||
var reversedList = reverseListMethods.execute(millionElementsList);
|
||||
bh.consume(reversedList);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumList(Blackhole bh) {
|
||||
var res = sumList.execute(millionElementsList);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return a number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void sumListLeftFold(Blackhole bh) {
|
||||
var res = sumListLeftFold.execute(millionElementsList);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return a number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumListFallback(Blackhole bh) {
|
||||
var res = sumListFallback.execute(millionElementsList);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return a number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumListMethods(Blackhole bh) {
|
||||
var res = sumListMethods.execute(millionElementsList);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return a number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchMapReverseList(Blackhole bh) {
|
||||
var res = mapReverseList.execute(millionElementsList);
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchMapReverseCurryList(Blackhole bh) {
|
||||
var res = mapReverseListCurry.execute(millionElementsList);
|
||||
bh.consume(res);
|
||||
}
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package org.enso.interpreter.bench.benchmarks.semantic;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.enso.interpreter.bench.Utils;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Value;
|
||||
import org.graalvm.polyglot.io.IOAccess;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.infra.BenchmarkParams;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Fork(1)
|
||||
@Warmup(iterations = 5)
|
||||
@Measurement(iterations = 5)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
public class CallableBenchmarks {
|
||||
private static final long HUNDRED_MILLION = 100_000_000L;
|
||||
private static final String SUM_TCO_FROM_CALL_CODE =
|
||||
"""
|
||||
from Standard.Base.Data.Numbers import all
|
||||
|
||||
type Foo
|
||||
|
||||
Foo.from (that : Number) current=0 =
|
||||
if current == 0 then that else @Tail_Call Foo.from (that + current) (current - 1)
|
||||
|
||||
main = sumTo ->
|
||||
res = Foo.from 0 sumTo
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String SUM_TCO_METHOD_CALL_CODE =
|
||||
"""
|
||||
summator = acc -> current ->
|
||||
if current == 0 then acc else @Tail_Call summator (acc + current) (current - 1)
|
||||
|
||||
main = sumTo ->
|
||||
res = summator 0 sumTo
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String SUM_TCO_METHOD_CALL_WITH_NAMED_ARGUMENTS_CODE =
|
||||
"""
|
||||
summator = acc -> current ->
|
||||
if current == 0 then acc else @Tail_Call summator (current = current - 1) (acc = acc + current)
|
||||
|
||||
main = sumTo ->
|
||||
res = summator current=sumTo acc=0
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String SUM_TCO_METHOD_CALL_WITH_DEFAULTED_ARGUMENTS_CODE =
|
||||
"""
|
||||
summator = (acc = 0) -> current ->
|
||||
if current == 0 then acc else @Tail_Call summator (current = current - 1) (acc = acc + current)
|
||||
|
||||
main = sumTo ->
|
||||
res = summator current=sumTo
|
||||
res
|
||||
""";
|
||||
|
||||
private Context context;
|
||||
private Value sumTCOfromCall;
|
||||
private Value sumTCOmethodCall;
|
||||
private Value sumTCOmethodCallWithNamedArguments;
|
||||
private Value sumTCOmethodCallWithDefaultedArguments;
|
||||
|
||||
@Setup
|
||||
public void initializeBenchmarks(BenchmarkParams params) {
|
||||
this.context =
|
||||
Context.newBuilder()
|
||||
.allowExperimentalOptions(true)
|
||||
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
|
||||
.logHandler(System.err)
|
||||
.allowIO(IOAccess.ALL)
|
||||
.allowAllAccess(true)
|
||||
.option(
|
||||
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
|
||||
Paths.get("../../distribution/component").toFile().getAbsolutePath())
|
||||
.build();
|
||||
|
||||
this.sumTCOfromCall = Utils.getMainMethod(context, SUM_TCO_FROM_CALL_CODE);
|
||||
this.sumTCOmethodCall = Utils.getMainMethod(context, SUM_TCO_METHOD_CALL_CODE);
|
||||
this.sumTCOmethodCallWithNamedArguments =
|
||||
Utils.getMainMethod(context, SUM_TCO_METHOD_CALL_WITH_NAMED_ARGUMENTS_CODE);
|
||||
this.sumTCOmethodCallWithDefaultedArguments =
|
||||
Utils.getMainMethod(context, SUM_TCO_METHOD_CALL_WITH_DEFAULTED_ARGUMENTS_CODE);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumTCOfromCall(Blackhole bh) {
|
||||
var res = sumTCOfromCall.execute(HUNDRED_MILLION);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumTCOmethodCall(Blackhole bh) {
|
||||
var res = sumTCOmethodCall.execute(HUNDRED_MILLION);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumTCOmethodCallWithNamedArguments(Blackhole bh) {
|
||||
var res = sumTCOmethodCallWithNamedArguments.execute(HUNDRED_MILLION);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumTCOmethodCallWithDefaultedArguments(Blackhole bh) {
|
||||
var res = sumTCOmethodCallWithDefaultedArguments.execute(HUNDRED_MILLION);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.enso.interpreter.test.TestBase;
|
||||
import org.enso.polyglot.MethodNames.Module;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.graalvm.polyglot.Context;
|
||||
@ -34,7 +33,7 @@ import org.openjdk.jmh.infra.BenchmarkParams;
|
||||
@Measurement(iterations = 3, time = 3)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
public class IfVsCaseBenchmarks extends TestBase {
|
||||
public class IfVsCaseBenchmarks {
|
||||
private static final int INPUT_VEC_SIZE = 100_000;
|
||||
private Context ctx;
|
||||
private Value ifBench3;
|
@ -0,0 +1,94 @@
|
||||
package org.enso.interpreter.bench.benchmarks.semantic;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.enso.interpreter.bench.Utils;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Value;
|
||||
import org.graalvm.polyglot.io.IOAccess;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.infra.BenchmarkParams;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Fork(1)
|
||||
@Warmup(iterations = 5)
|
||||
@Measurement(iterations = 5)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
public class NamedDefaultedArgumentBenchmarks {
|
||||
private static long HUNDRED_MILLION = 100_000_000L;
|
||||
private static final String SUM_TCO_WITH_NAMED_ARGUMENTS_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.Numbers
|
||||
main = sumTo ->
|
||||
summator = acc -> current ->
|
||||
if current == 0 then acc else @Tail_Call summator (current = current - 1) (acc = acc + current)
|
||||
|
||||
res = summator current=sumTo acc=0
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String SUM_TCO_WITH_DEFAULTED_ARGUMENTS_CODE =
|
||||
"""
|
||||
import Standard.Base.Data.Numbers
|
||||
main = sumTo ->
|
||||
summator = (acc = 0) -> current ->
|
||||
if current == 0 then acc else @Tail_Call summator (current = current - 1) (acc = acc + current)
|
||||
|
||||
res = summator (current = sumTo)
|
||||
res
|
||||
""";
|
||||
|
||||
private Context context;
|
||||
private Value sumTCOWithNamedArguments;
|
||||
private Value sumTCOWithDefaultedArguments;
|
||||
|
||||
@Setup
|
||||
public void initializeBenchmarks(BenchmarkParams params) {
|
||||
this.context =
|
||||
Context.newBuilder()
|
||||
.allowExperimentalOptions(true)
|
||||
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
|
||||
.logHandler(System.err)
|
||||
.allowIO(IOAccess.ALL)
|
||||
.allowAllAccess(true)
|
||||
.option(
|
||||
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
|
||||
Paths.get("../../distribution/component").toFile().getAbsolutePath())
|
||||
.build();
|
||||
|
||||
this.sumTCOWithNamedArguments = Utils.getMainMethod(context, SUM_TCO_WITH_NAMED_ARGUMENTS_CODE);
|
||||
this.sumTCOWithDefaultedArguments =
|
||||
Utils.getMainMethod(context, SUM_TCO_WITH_DEFAULTED_ARGUMENTS_CODE);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumTCOWithNamedArgs(Blackhole bh) {
|
||||
var res = sumTCOWithNamedArguments.execute(HUNDRED_MILLION);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumTCOWithDefaultArgs(Blackhole bh) {
|
||||
var res = sumTCOWithDefaultedArguments.execute(HUNDRED_MILLION);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return number");
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
package org.enso.interpreter.bench.benchmarks.semantic;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import org.enso.interpreter.bench.Utils;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Value;
|
||||
import org.graalvm.polyglot.io.IOAccess;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
import org.openjdk.jmh.infra.BenchmarkParams;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Fork(1)
|
||||
@Warmup(iterations = 5)
|
||||
@Measurement(iterations = 5)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
public class RecursionBenchmarks {
|
||||
private static final String SUM_TCO_CODE =
|
||||
"""
|
||||
main = sumTo ->
|
||||
summator = acc -> current ->
|
||||
if current == 0 then acc else @Tail_Call summator acc+current current-1
|
||||
|
||||
res = summator 0 sumTo
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String SUM_TCO_FOLD_LIKE_CODE =
|
||||
"""
|
||||
main = sumTo ->
|
||||
summator = acc -> i -> f ->
|
||||
if i == 0 then acc else @Tail_Call summator (f acc i) (i - 1) f
|
||||
res = summator 0 sumTo (x -> y -> x + y)
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String SUM_RECURSIVE_CODE =
|
||||
"""
|
||||
main = sumTo ->
|
||||
summator = i -> if i == 0 then 0 else i + summator (i - 1)
|
||||
res = summator sumTo
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String OVERSATURATED_RECURSIVE_CALL_TCO_CODE =
|
||||
"""
|
||||
main = sumTo ->
|
||||
summator = acc -> i -> f ->
|
||||
if i == 0 then acc else @Tail_Call summator (f acc i) (i - 1) f
|
||||
res = summator 0 sumTo (x -> y -> x + y)
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String SUM_STATE_TCO_CODE =
|
||||
"""
|
||||
from Standard.Base.Data.Numbers import Number
|
||||
import Standard.Base.Runtime.State
|
||||
|
||||
stateSum = n ->
|
||||
acc = State.get Number
|
||||
State.put Number (acc + n)
|
||||
if n == 0 then State.get Number else @Tail_Call stateSum (n - 1)
|
||||
|
||||
main = sumTo ->
|
||||
res = State.run Number 0 (stateSum sumTo)
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String SUM_TCO_WITH_EVAL_CODE =
|
||||
"""
|
||||
import Standard.Base.Runtime.Debug
|
||||
|
||||
main = sumTo ->
|
||||
summator = acc -> current ->
|
||||
if current == 0 then acc else Debug.eval "@Tail_Call summator (acc + current) (current - 1)"
|
||||
|
||||
res = summator 0 sumTo
|
||||
res
|
||||
""";
|
||||
|
||||
private static final String NESTED_THUNK_SUM_CODE =
|
||||
"""
|
||||
from Standard.Base.Data.Numbers import Number
|
||||
import Standard.Base.Runtime.State
|
||||
import Standard.Base.Nothing.Nothing
|
||||
|
||||
doNTimes = n -> ~block ->
|
||||
block
|
||||
if n == 1 then Nothing else @Tail_Call doNTimes n-1 block
|
||||
|
||||
main = n ->
|
||||
block =
|
||||
x = State.get Number
|
||||
State.put Number x+1
|
||||
|
||||
res = State.run Number 0 (doNTimes n block)
|
||||
res
|
||||
""";
|
||||
private static final long HUNDRED_MILLION = 100_000_000L;
|
||||
private static final long HUNDRED = 100L;
|
||||
|
||||
private Context context;
|
||||
private Value sumTCO;
|
||||
private Value sumTCOWithEval;
|
||||
private Value sumTCOFoldLike;
|
||||
private Value sumRecursive;
|
||||
private Value oversaturatedRecursiveCall;
|
||||
private Value sumStateTCO;
|
||||
private Value nestedThunkSum;
|
||||
|
||||
@Setup
|
||||
public void initializeBenchmarks(BenchmarkParams params) {
|
||||
this.context =
|
||||
Context.newBuilder()
|
||||
.allowExperimentalOptions(true)
|
||||
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
|
||||
.logHandler(System.err)
|
||||
.allowIO(IOAccess.ALL)
|
||||
.allowAllAccess(true)
|
||||
.option(
|
||||
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
|
||||
Paths.get("../../distribution/component").toFile().getAbsolutePath())
|
||||
.build();
|
||||
|
||||
this.sumTCO = Utils.getMainMethod(context, SUM_TCO_CODE);
|
||||
this.sumTCOWithEval = Utils.getMainMethod(context, SUM_TCO_WITH_EVAL_CODE);
|
||||
this.sumTCOFoldLike = Utils.getMainMethod(context, SUM_TCO_FOLD_LIKE_CODE);
|
||||
this.sumRecursive = Utils.getMainMethod(context, SUM_RECURSIVE_CODE);
|
||||
this.oversaturatedRecursiveCall =
|
||||
Utils.getMainMethod(context, OVERSATURATED_RECURSIVE_CALL_TCO_CODE);
|
||||
this.sumStateTCO = Utils.getMainMethod(context, SUM_STATE_TCO_CODE);
|
||||
this.nestedThunkSum = Utils.getMainMethod(context, NESTED_THUNK_SUM_CODE);
|
||||
}
|
||||
|
||||
private Value runOnHundredMillion(Value function) {
|
||||
var res = function.execute(HUNDRED_MILLION);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return number, but got " + res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumTCO(Blackhole bh) {
|
||||
var res = runOnHundredMillion(sumTCO);
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumTCOWithEval(Blackhole bh) {
|
||||
var res = runOnHundredMillion(sumTCOWithEval);
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumTCOFoldLike(Blackhole bh) {
|
||||
var res = runOnHundredMillion(sumTCOFoldLike);
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumRecursive(Blackhole bh) {
|
||||
var res = sumRecursive.execute(HUNDRED);
|
||||
if (!res.fitsInLong()) {
|
||||
throw new AssertionError("Should return number, but got " + res);
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchOversaturatedRecursiveCall(Blackhole bh) {
|
||||
var res = runOnHundredMillion(oversaturatedRecursiveCall);
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchSumStateTCO(Blackhole bh) {
|
||||
var res = runOnHundredMillion(sumStateTCO);
|
||||
bh.consume(res);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchNestedThunkSum(Blackhole bh) {
|
||||
var res = nestedThunkSum.execute(HUNDRED_MILLION);
|
||||
if (!res.isNull()) {
|
||||
throw new AssertionError("Should return Nothing, but got " + res);
|
||||
}
|
||||
bh.consume(res);
|
||||
}
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
package org.enso.interpreter.bench.benchmarks.semantic;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import org.openjdk.jmh.infra.BenchmarkParams;
|
||||
|
||||
@ -28,7 +27,7 @@ final class SrcUtil {
|
||||
static Source read(String benchmarkName) throws IOException {
|
||||
String resource = benchmarkName + ".enso";
|
||||
var url = SrcUtil.class.getResource(resource);
|
||||
assertNotNull("Searching for " + resource, url);
|
||||
Objects.requireNonNull(url, "Searching for " + resource);
|
||||
return Source.newBuilder("enso", url).name(resource).build();
|
||||
}
|
||||
}
|
@ -1,15 +1,18 @@
|
||||
package org.enso.interpreter.bench.benchmarks.semantic;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.enso.interpreter.test.TestBase;
|
||||
import java.util.logging.Level;
|
||||
import org.enso.polyglot.MethodNames;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Value;
|
||||
import org.graalvm.polyglot.io.IOAccess;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
@ -29,7 +32,7 @@ import org.openjdk.jmh.infra.BenchmarkParams;
|
||||
@Measurement(iterations = 3, time = 3)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
public class WarningBenchmarks extends TestBase {
|
||||
public class WarningBenchmarks {
|
||||
private static final int INPUT_VEC_SIZE = 10_000;
|
||||
private static final int INPUT_DIFF_VEC_SIZE = 10_000;
|
||||
private Context ctx;
|
||||
@ -68,7 +71,17 @@ public class WarningBenchmarks extends TestBase {
|
||||
|
||||
@Setup
|
||||
public void initializeBench(BenchmarkParams params) throws IOException {
|
||||
ctx = createDefaultContext();
|
||||
this.ctx =
|
||||
Context.newBuilder()
|
||||
.allowExperimentalOptions(true)
|
||||
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
|
||||
.logHandler(System.err)
|
||||
.allowIO(IOAccess.ALL)
|
||||
.allowAllAccess(true)
|
||||
.option(
|
||||
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
|
||||
Paths.get("../../distribution/component").toFile().getAbsolutePath())
|
||||
.build();
|
||||
var random = new Random(42);
|
||||
|
||||
benchmarkName = SrcUtil.findName(params);
|
@ -237,6 +237,16 @@ main = Warning.attach "foo" Nothing
|
||||
assertThat(nothingWithWarn.isMetaObject(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nothingShouldBeNull() {
|
||||
var src = """
|
||||
import Standard.Base.Nothing.Nothing
|
||||
main = Nothing
|
||||
""";
|
||||
var nothing = TestBase.evalModule(ctx, src);
|
||||
assertThat(nothing.isNull(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void numbersAreEitherIntegerOrFloat() throws Exception {
|
||||
var g = generator();
|
@ -49,6 +49,17 @@ public class AssertionsTest extends TestBase {
|
||||
out.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jvmAssertionsAreEnabled() {
|
||||
boolean assertsOn = false;
|
||||
assert assertsOn = true;
|
||||
assertTrue(
|
||||
"JVM assertions must be enabled (with -ea cmd line option) in order to run all the tests"
|
||||
+ " inside runtime-integration-tests project. Note that there are some features in the"
|
||||
+ " runtime that work only with the JVM assertions enabled.",
|
||||
assertsOn);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertionsAreEnabled() {
|
||||
EnsoContext ensoCtx =
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user