Format Java sources in benchmark configuration (#8638)

I noticed that sources in `runtime/bench` are not formatted at all. Turns out that the `JavaFormatterPlugin` does not override `javafmt` task for the `Benchmark` configuration. After some failed attempts, I have just redefined the `Benchmark/javafmt` task in the `runtime` project. After all, the `runtime` project is almost the only project where we have any Java benchmarks.

# Important Notes
`javafmtAll` now also formats sources in `runtime/bench/src/java`.
This commit is contained in:
Pavel Marek 2023-12-28 18:06:06 +01:00 committed by GitHub
parent 2d628263ff
commit 48a3c14ee5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 450 additions and 449 deletions

View File

@ -1533,6 +1533,28 @@ 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 / testOptions += Tests.Argument(

View File

@ -20,7 +20,9 @@ public class BenchmarkItem {
return previousResults;
}
/** @return Best historic score for the given benchmark (including current run). */
/**
* @return Best historic score for the given benchmark (including current run).
*/
public double getBestScore() {
return previousResults.getBestScore().orElse(result.getScore());
}

View File

@ -18,7 +18,9 @@ import org.openjdk.jmh.runner.options.OptionsBuilder;
public class BenchmarksRunner {
public static final File REPORT_FILE = new File("./bench-report.xml");
/** @return A list of qualified names of all benchmarks visible to JMH. */
/**
* @return A list of qualified names of all benchmarks visible to JMH.
*/
public List<String> getAvailable() {
return BenchmarkList.defaultList().getAll(null, new ArrayList<>()).stream()
.map(BenchmarkListEntry::getUsername)
@ -32,14 +34,13 @@ public class BenchmarksRunner {
* @return a {@link BenchmarkItem} containing current run result and historical results.
*/
public BenchmarkItem run(String label) throws RunnerException, JAXBException {
ChainedOptionsBuilder builder = new OptionsBuilder()
.jvmArgsAppend("-Xss16M", "-Dpolyglot.engine.MultiTier=false")
.include("^" + label + "$");
ChainedOptionsBuilder builder =
new OptionsBuilder()
.jvmArgsAppend("-Xss16M", "-Dpolyglot.engine.MultiTier=false")
.include("^" + label + "$");
if (Boolean.getBoolean("bench.compileOnly")) {
builder
.measurementIterations(1)
.warmupIterations(0);
builder.measurementIterations(1).warmupIterations(0);
}
Options benchmarkOptions = builder.build();

View File

@ -1,9 +1,5 @@
package org.enso.interpreter.bench;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
@ -11,6 +7,10 @@ import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElementWrapper;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/** Historic runs report. Supports XML serialization. */
@XmlRootElement

View File

@ -1,13 +1,13 @@
package org.enso.interpreter.bench;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElementWrapper;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlTransient;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
/** Contains historic results for a single benchmark identified by label. */
@XmlRootElement
@ -53,7 +53,9 @@ public class ReportItem {
getScores().add(score);
}
/** @return The best (lowest) historic result for this benchmark. */
/**
* @return The best (lowest) historic result for this benchmark.
*/
@XmlTransient
public Optional<Double> getBestScore() {
OptionalDouble min = getScores().stream().mapToDouble(s -> s).min();

View File

@ -1,11 +1,9 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.io.ByteArrayOutputStream;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.logging.Level;
import org.enso.polyglot.RuntimeOptions;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Engine;
@ -38,17 +36,15 @@ public class ArrayProxyBenchmarks {
Engine eng =
Engine.newBuilder()
.allowExperimentalOptions(true)
.option(
RuntimeOptions.LOG_LEVEL,
Level.WARNING.getName()
)
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath())
.build();
var ctx = Context.newBuilder().engine(eng).allowIO(IOAccess.ALL).allowAllAccess(true).build();
var code = """
var code =
"""
import Standard.Base.Data.Vector.Vector
import Standard.Base.Data.Array_Proxy.Array_Proxy
sum arr =
@ -92,8 +88,7 @@ public class ArrayProxyBenchmarks {
test_builder = "make_delegating_vector";
break;
default:
throw new IllegalStateException(
"Unexpected benchmark: " + params.getBenchmark());
throw new IllegalStateException("Unexpected benchmark: " + params.getBenchmark());
}
this.arrayOfNumbers = getMethod.apply(test_builder).execute(self, length);
this.sum = getMethod.apply("sum");
@ -133,8 +128,7 @@ public class ArrayProxyBenchmarks {
long expectedResult = length * 3L + (5L * (length * (length - 1L) / 2L));
boolean isResultCorrect = result == expectedResult;
if (!isResultCorrect) {
throw new AssertionError(
"Expecting " + expectedResult + " but was " + result);
throw new AssertionError("Expecting " + expectedResult + " but was " + result);
}
matter.consume(result);
}

View File

@ -1,7 +1,6 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.util.concurrent.TimeUnit;
import org.enso.interpreter.bench.fixtures.semantic.CallableFixtures;
import org.enso.interpreter.test.DefaultInterpreterRunner;
import org.openjdk.jmh.annotations.Benchmark;
@ -18,8 +17,7 @@ import org.openjdk.jmh.annotations.Warmup;
@Measurement(iterations = 5)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class CallableBenchmarks {
private static final CallableFixtures argumentFixtures =
new CallableFixtures();
private static final CallableFixtures argumentFixtures = new CallableFixtures();
private void runOnHundredMillion(DefaultInterpreterRunner.MainMethod main) {
main.mainFunction().value().execute(argumentFixtures.hundredMillion());

View File

@ -1,6 +1,5 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.io.ByteArrayOutputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
@ -10,7 +9,6 @@ import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.enso.polyglot.MethodNames.Module;
import org.enso.polyglot.RuntimeOptions;
import org.graalvm.polyglot.Context;
@ -30,8 +28,8 @@ import org.openjdk.jmh.infra.BenchmarkParams;
import org.openjdk.jmh.infra.Blackhole;
/**
* Benchmarks for `Any.==` method. This benchmark takes two vectors as input, and compares each
* pair of elements with `==`.
* Benchmarks for `Any.==` method. This benchmark takes two vectors as input, and compares each pair
* of elements with `==`.
*/
@BenchmarkMode(Mode.AverageTime)
@Fork(1)
@ -43,18 +41,16 @@ public class EqualsBenchmarks {
private static final int primitiveVectorSize = 4_000;
private static final int stringsVectorSize = 3_000;
/**
* Maximum length of randomly generated strings.
*/
/** Maximum length of randomly generated strings. */
private static final int maxStringSize = 20;
/**
* Maximum depth of a tree (Node type). Every Node can have up to 5 children.
*/
/** Maximum depth of a tree (Node type). Every Node can have up to 5 children. */
private static final int maxTreeDepth = 4;
/**
* Size of the vector of trees (Node type).
*/
/** Size of the vector of trees (Node type). */
private static final int treeVectorSize = 500;
private Value module;
private Value benchFunc;
@ -62,24 +58,24 @@ public class EqualsBenchmarks {
public void initializeBenchmark(BenchmarkParams params) throws Exception {
var random = new Random(42);
var ctx = Context.newBuilder()
.allowExperimentalOptions(true)
.option(
RuntimeOptions.LOG_LEVEL,
Level.WARNING.getName()
)
.logHandler(System.err)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath()
).build();
var ctx =
Context.newBuilder()
.allowExperimentalOptions(true)
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
.logHandler(System.err)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath())
.build();
var benchmarkName = SrcUtil.findName(params);
var codeBuilder = new StringBuilder("""
var codeBuilder =
new StringBuilder(
"""
import Standard.Base.Data.Range.Extensions
type Node
C1 f1
C2 f1 f2
@ -88,14 +84,13 @@ public class EqualsBenchmarks {
C5 f1 f2 f3 f4 f5
Nil
Value value
eq_vec vec1 vec2 =
(0.up_to vec1.length).map idx->
(vec1.at idx) == (vec2.at idx)
eq x y = x == y
"""
);
""");
// Indexes where `True` is expected. Inside the generated vectors, on a predefined indexes,
// we put "constant" values, such that when the elements at these indexes are compared,
// `True` is returned.
@ -103,68 +98,53 @@ public class EqualsBenchmarks {
switch (benchmarkName) {
case "equalsPrimitives" -> {
trueExpectedAt = Set.of(
primitiveVectorSize / 2,
primitiveVectorSize / 4,
primitiveVectorSize / 8,
primitiveVectorSize / 16,
primitiveVectorSize / 32,
primitiveVectorSize / 64
);
trueExpectedAt =
Set.of(
primitiveVectorSize / 2,
primitiveVectorSize / 4,
primitiveVectorSize / 8,
primitiveVectorSize / 16,
primitiveVectorSize / 32,
primitiveVectorSize / 64);
codeBuilder
.append(
generateVectorOfPrimitives(primitiveVectorSize, "vec1", 42, trueExpectedAt, random)
)
generateVectorOfPrimitives(primitiveVectorSize, "vec1", 42, trueExpectedAt, random))
.append("\n")
.append(
generateVectorOfPrimitives(primitiveVectorSize, "vec2", 42, trueExpectedAt, random)
)
generateVectorOfPrimitives(primitiveVectorSize, "vec2", 42, trueExpectedAt, random))
.append("\n");
}
case "equalsStrings" -> {
trueExpectedAt = Set.of(
treeVectorSize / 2,
treeVectorSize / 4,
treeVectorSize / 8
);
trueExpectedAt = Set.of(treeVectorSize / 2, treeVectorSize / 4, treeVectorSize / 8);
codeBuilder
.append(
generateVectorOfStrings(stringsVectorSize, "vec1", "AAA", trueExpectedAt, random)
)
generateVectorOfStrings(stringsVectorSize, "vec1", "AAA", trueExpectedAt, random))
.append("\n")
.append(
generateVectorOfStrings(stringsVectorSize, "vec2", "AAA", trueExpectedAt, random)
)
generateVectorOfStrings(stringsVectorSize, "vec2", "AAA", trueExpectedAt, random))
.append("\n");
}
case "equalsTrees" -> {
trueExpectedAt = Set.of(
treeVectorSize / 2,
treeVectorSize / 4,
treeVectorSize / 8,
treeVectorSize / 16
);
trueExpectedAt =
Set.of(treeVectorSize / 2, treeVectorSize / 4, treeVectorSize / 8, treeVectorSize / 16);
codeBuilder
.append(
generateVectorOfTrees(treeVectorSize, "vec1", maxTreeDepth, createNilNode(), trueExpectedAt, random)
)
generateVectorOfTrees(
treeVectorSize, "vec1", maxTreeDepth, createNilNode(), trueExpectedAt, random))
.append("\n")
.append(
generateVectorOfTrees(treeVectorSize, "vec2", maxTreeDepth, createNilNode(), trueExpectedAt, random)
)
generateVectorOfTrees(
treeVectorSize, "vec2", maxTreeDepth, createNilNode(), trueExpectedAt, random))
.append("\n");
}
default ->
throw new IllegalStateException("Unexpected benchmark: " + params.getBenchmark());
default -> throw new IllegalStateException("Unexpected benchmark: " + params.getBenchmark());
}
codeBuilder.append("""
bench x = eq_vec vec1 vec2
""");
module = ctx.eval(
SrcUtil.source(benchmarkName, codeBuilder.toString())
);
module = ctx.eval(SrcUtil.source(benchmarkName, codeBuilder.toString()));
benchFunc = module.invokeMember(Module.EVAL_EXPRESSION, "bench");
@ -181,8 +161,9 @@ public class EqualsBenchmarks {
}
/**
* Iterates over {@link #primitiveVectorSize} long vector of random generated primitive values - integers,
* doubles, and strings
* Iterates over {@link #primitiveVectorSize} long vector of random generated primitive values -
* integers, doubles, and strings
*
* @param blackHole
*/
@Benchmark
@ -207,21 +188,26 @@ public class EqualsBenchmarks {
/**
* Generates source code for a vector of primitive values. The vector will contain integers and
* doubles. Count of elements of these different value types is equally distributed,
* i.e., there is exact same amount of integers and doubles. Vector is
* shuffled, so that there should not be a long consecutive range of values of just one type.
* <p>
* Generates code of form {@code vecName = [...]}
* doubles. Count of elements of these different value types is equally distributed, i.e., there
* is exact same amount of integers and doubles. Vector is shuffled, so that there should not be a
* long consecutive range of values of just one type.
*
* <p>Generates code of form {@code vecName = [...]}
*
* @param totalSize Total size of the generated vector.
* @param vecName Name of the generated vector.
* @param identityElem A primitive element considered an identity with respect to `==` operator,
* will be put in indexes denoted by {@code constantIdxs}
* will be put in indexes denoted by {@code constantIdxs}
* @param constantIdxs Indexes where {@code identityElem} will be put.
* @param random Random number generator.
* @return Source of the generated vector
*/
private static String generateVectorOfPrimitives(int totalSize, String vecName, Object identityElem, Collection<Integer> constantIdxs, Random random) {
private static String generateVectorOfPrimitives(
int totalSize,
String vecName,
Object identityElem,
Collection<Integer> constantIdxs,
Random random) {
var partSize = totalSize / 2;
List<Object> primitiveValues = new ArrayList<>();
random.ints(partSize).forEach(primitiveValues::add);
@ -245,7 +231,12 @@ public class EqualsBenchmarks {
return sb.toString();
}
private static String generateVectorOfStrings(int size, String vecName, String identityElem, Collection<Integer> identityIdxs, Random random) {
private static String generateVectorOfStrings(
int size,
String vecName,
String identityElem,
Collection<Integer> identityIdxs,
Random random) {
var sb = new StringBuilder();
sb.append(vecName).append(" = [");
for (int i = 0; i < size; i++) {
@ -263,25 +254,29 @@ public class EqualsBenchmarks {
}
/**
* Generates source code for a vector of trees (Node type), i.e., generates an expression
* {@code vecName = [...]}.
* Generates source code for a vector of trees (Node type), i.e., generates an expression {@code
* vecName = [...]}.
*
* @param size Total size of the generated vector.
* @param vecName How the vector should be named.
* @param maxDepth Maximum depth of the generated tree. Note that there is no lower bound, so
* the generated tree can have depth 1.
* @param identityNode A node that is considered an identity with respect to `==` operator.
* This node will be put on every indes of {@code constantIdxs}.
* @param maxDepth Maximum depth of the generated tree. Note that there is no lower bound, so the
* generated tree can have depth 1.
* @param identityNode A node that is considered an identity with respect to `==` operator. This
* node will be put on every indes of {@code constantIdxs}.
* @param constantIdxs Indexes in the vector where {@code identityNode} should be put.
* @param random Random number generator.
* @return Source code for the generated tree.
*/
private static String generateVectorOfTrees(int size, String vecName, int maxDepth, Node identityNode, Collection<Integer> constantIdxs, Random random) {
private static String generateVectorOfTrees(
int size,
String vecName,
int maxDepth,
Node identityNode,
Collection<Integer> constantIdxs,
Random random) {
var trees = new ArrayList<Node>();
for (int i = 0; i < size; i++) {
trees.add(
generateTree(null, 0, random, maxDepth)
);
trees.add(generateTree(null, 0, random, maxDepth));
}
for (Integer constantIdx : constantIdxs) {
trees.set(constantIdx, identityNode);
@ -302,11 +297,7 @@ public class EqualsBenchmarks {
node = new NilNode(currDepth, parent);
} else {
if (random.nextBoolean() && currDepth > 0) {
node = new ValueNode(
currDepth,
parent,
random.nextInt()
);
node = new ValueNode(currDepth, parent, random.nextInt());
} else {
node = new NodeWithChildren(currDepth, parent);
// childCount is between 1..5
@ -318,26 +309,21 @@ public class EqualsBenchmarks {
}
if (parent instanceof NodeWithChildren parentWithChildren) {
parentWithChildren.addChild(node);
} else if (parent != null){
} else if (parent != null) {
throw new AssertionError("expected parent to be NodeWithChildren or null");
}
return node;
}
private static final String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQESRTUVWXYZ";
private static String randomString(int size, Random random) {
var sb = new StringBuilder(size);
random
.ints(size, 0, characters.length())
.mapToObj(characters::charAt)
.forEach(sb::append);
random.ints(size, 0, characters.length()).mapToObj(characters::charAt).forEach(sb::append);
return sb.toString();
}
/**
* A simple hierarchy of Node classes that simplifies source code generation.
*/
/** A simple hierarchy of Node classes that simplifies source code generation. */
abstract static class Node {
final int depth;
final Node parent;
@ -352,6 +338,7 @@ public class EqualsBenchmarks {
private static final class ValueNode extends Node {
final int value;
ValueNode(int depth, Node parent, int value) {
super(depth, parent);
this.value = value;
@ -388,14 +375,16 @@ public class EqualsBenchmarks {
@Override
public String createSource() {
String ctor = switch(children.size()) {
case 1 -> "(Node.C1 ";
case 2 -> "(Node.C2 ";
case 3 -> "(Node.C3 ";
case 4 -> "(Node.C4 ";
case 5 -> "(Node.C5 ";
default -> throw new AssertionError("Unexpected number of children: " + children.size());
};
String ctor =
switch (children.size()) {
case 1 -> "(Node.C1 ";
case 2 -> "(Node.C2 ";
case 3 -> "(Node.C3 ";
case 4 -> "(Node.C4 ";
case 5 -> "(Node.C5 ";
default -> throw new AssertionError(
"Unexpected number of children: " + children.size());
};
var sb = new StringBuilder();
sb.append(ctor);
for (Node child : children) {

View File

@ -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;
@ -49,26 +48,24 @@ public class IfVsCaseBenchmarks extends TestBase {
@Setup
public void initializeBench(BenchmarkParams params) throws IOException {
OutputStream out = new ByteArrayOutputStream();
ctx = Context.newBuilder("enso")
.allowAllAccess(true)
.option(
RuntimeOptions.LOG_LEVEL,
Level.WARNING.getName()
)
.logHandler(System.err)
.out(out)
.err(out)
.allowIO(IOAccess.ALL)
.allowExperimentalOptions(true)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath()
)
.option("engine.MultiTier", "true")
.option("engine.BackgroundCompilation", "true")
.build();
ctx =
Context.newBuilder("enso")
.allowAllAccess(true)
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
.logHandler(System.err)
.out(out)
.err(out)
.allowIO(IOAccess.ALL)
.allowExperimentalOptions(true)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath())
.option("engine.MultiTier", "true")
.option("engine.BackgroundCompilation", "true")
.build();
var code = """
var code =
"""
from Standard.Base import all
type My_Type
@ -142,10 +139,13 @@ public class IfVsCaseBenchmarks extends TestBase {
var src = SrcUtil.source(benchmarkName, code);
Value module = ctx.eval(src);
ifBench3 = Objects.requireNonNull(module.invokeMember(Module.EVAL_EXPRESSION, "if_bench_3"));
caseBench3 = Objects.requireNonNull(module.invokeMember(Module.EVAL_EXPRESSION, "case_bench_3"));
caseBench3 =
Objects.requireNonNull(module.invokeMember(Module.EVAL_EXPRESSION, "case_bench_3"));
ifBench6 = Objects.requireNonNull(module.invokeMember(Module.EVAL_EXPRESSION, "if_bench_6"));
ifBench6In = Objects.requireNonNull(module.invokeMember(Module.EVAL_EXPRESSION, "if_bench_6_in"));
caseBench6 = Objects.requireNonNull(module.invokeMember(Module.EVAL_EXPRESSION, "case_bench_6"));
ifBench6In =
Objects.requireNonNull(module.invokeMember(Module.EVAL_EXPRESSION, "if_bench_6_in"));
caseBench6 =
Objects.requireNonNull(module.invokeMember(Module.EVAL_EXPRESSION, "case_bench_6"));
createVec = Objects.requireNonNull(module.invokeMember(Module.EVAL_EXPRESSION, "create_vec"));
// So far, input is a vector of My_Type.Value with all fields set to True
inputVec = createMyTypeAllTrue(INPUT_VEC_SIZE);
@ -156,9 +156,7 @@ public class IfVsCaseBenchmarks extends TestBase {
ctx.close();
}
/**
* Iterates over a vector of {@code My_Type} values with True only fields.
*/
/** Iterates over a vector of {@code My_Type} values with True only fields. */
@Benchmark
public void ifBench3() {
Value res = ifBench3.execute(inputVec);
@ -195,9 +193,7 @@ public class IfVsCaseBenchmarks extends TestBase {
}
}
/**
* Creates a vector of {@code My_Type} with all True fields
*/
/** Creates a vector of {@code My_Type} with all True fields */
private Value createMyTypeAllTrue(int size) {
List<List<Boolean>> inputPolyVec = new ArrayList<>();
for (int i = 0; i < size; i++) {

View File

@ -1,11 +1,9 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.io.ByteArrayOutputStream;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.logging.Level;
import org.enso.polyglot.RuntimeOptions;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
@ -23,7 +21,6 @@ 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 = 3)
@ -41,22 +38,21 @@ public class ListBenchmarks {
@Setup
public void initializeBenchmark(BenchmarkParams params) throws Exception {
var ctx = Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(
RuntimeOptions.LOG_LEVEL,
Level.WARNING.getName()
)
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath()
).build();
var ctx =
Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath())
.build();
var benchmarkName = SrcUtil.findName(params);
var code = """
var code =
"""
from Standard.Base.Any import Any
from Standard.Base.Data.List.List import Cons, Nil
from Standard.Base.Data.Text import Text
@ -135,12 +131,12 @@ public class ListBenchmarks {
var module = ctx.eval(SrcUtil.source(benchmarkName, code));
this.self = module.invokeMember("get_associated_type");
Function<String,Value> getMethod = (name) -> module.invokeMember("get_method", self, name);
Function<String, Value> getMethod = (name) -> module.invokeMember("get_method", self, name);
this.plusOne = getMethod.apply("plus_one");
switch (benchmarkName) {
case "mapOverList" -> {
case "mapOverList" -> {
this.list = getMethod.apply("generator").execute(self, LENGTH_OF_EXPERIMENT);
this.zero = 0;
this.sum = getMethod.apply("sum");
@ -149,7 +145,7 @@ public class ListBenchmarks {
throw new AssertionError("Expecting a number " + this.oldSum);
}
}
case "mapAnyOverList" -> {
case "mapAnyOverList" -> {
this.list = getMethod.apply("generator").execute(self, LENGTH_OF_EXPERIMENT);
this.zero = 0;
this.sum = getMethod.apply("sum_any");
@ -158,7 +154,7 @@ public class ListBenchmarks {
throw new AssertionError("Expecting a number " + this.oldSum);
}
}
case "mapMultiOverList" -> {
case "mapMultiOverList" -> {
this.list = getMethod.apply("generator").execute(self, LENGTH_OF_EXPERIMENT);
this.zero = 0;
this.sum = getMethod.apply("sum_multi");
@ -167,7 +163,7 @@ public class ListBenchmarks {
throw new AssertionError("Expecting a number " + this.oldSum);
}
}
case "mapIntegerOverList" -> {
case "mapIntegerOverList" -> {
this.list = getMethod.apply("generator").execute(self, LENGTH_OF_EXPERIMENT);
this.zero = 0;
this.sum = getMethod.apply("sum_int");
@ -176,7 +172,7 @@ public class ListBenchmarks {
throw new AssertionError("Expecting a number " + this.oldSum);
}
}
case "mapVOverList" -> {
case "mapVOverList" -> {
this.list = getMethod.apply("generator").execute(self, LENGTH_OF_EXPERIMENT);
this.zero = getMethod.apply("v_zero").execute(self);
this.sum = getMethod.apply("v_sum_int");
@ -185,7 +181,7 @@ public class ListBenchmarks {
throw new AssertionError("Expecting a number " + this.oldSum);
}
}
case "mapConvOverList" -> {
case "mapConvOverList" -> {
this.list = getMethod.apply("generator").execute(self, LENGTH_OF_EXPERIMENT);
this.zero = getMethod.apply("v_zero").execute(self);
this.sum = getMethod.apply("v_sum_conv");
@ -194,7 +190,7 @@ public class ListBenchmarks {
throw new AssertionError("Expecting a number " + this.oldSum);
}
}
case "mapOverLazyList" -> {
case "mapOverLazyList" -> {
this.list = getMethod.apply("lenivy_generator").execute(self, LENGTH_OF_EXPERIMENT);
this.zero = 0;
this.sum = getMethod.apply("leniva_suma");
@ -253,4 +249,3 @@ public class ListBenchmarks {
hole.consume(result);
}
}

View File

@ -1,13 +1,10 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.AbstractList;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.logging.Level;
import org.enso.polyglot.RuntimeOptions;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
@ -25,7 +22,6 @@ 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 = 3)
@ -33,29 +29,28 @@ import org.openjdk.jmh.infra.Blackhole;
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
public class NestedPatternCompilationBenchmarks {
private Value self;
private String benchmarkName;
private String code;
private Context ctx;
private Value self;
private String benchmarkName;
private String code;
private Context ctx;
@Setup
public void initializeBenchmark(BenchmarkParams params) throws Exception {
ctx = Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(
RuntimeOptions.LOG_LEVEL,
Level.WARNING.getName()
)
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath()
).build();
@Setup
public void initializeBenchmark(BenchmarkParams params) throws Exception {
ctx =
Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath())
.build();
benchmarkName = SrcUtil.findName(params);
code = """
benchmarkName = SrcUtil.findName(params);
code =
"""
type List
Cons a b
Nil
@ -73,29 +68,27 @@ public class NestedPatternCompilationBenchmarks {
list_of_6 =
List.Cons 1 (List.Cons 2 (List.Cons 3 (List.Cons 4 (List.Cons 5 (List.Cons 6 List.Nil)))))
""";
}
@Benchmark
public void sumList(Blackhole hole) throws IOException {
// Compilation is included in the benchmark on purpose
var module = ctx.eval(SrcUtil.source(benchmarkName, code));
this.self = module.invokeMember("get_associated_type");
Function<String, Value> getMethod = (name) -> module.invokeMember("get_method", self, name);
var list = getMethod.apply("list_of_6").execute(self);
var result = getMethod.apply("test").execute(self, list);
if (!result.fitsInDouble()) {
throw new AssertionError("Shall be a double: " + result);
}
@Benchmark
public void sumList(Blackhole hole) throws IOException {
// Compilation is included in the benchmark on purpose
var module = ctx.eval(SrcUtil.source(benchmarkName, code));
this.self = module.invokeMember("get_associated_type");
Function<String,Value> getMethod = (name) -> module.invokeMember("get_method", self, name);
var list = getMethod.apply("list_of_6").execute(self);
var result = getMethod.apply("test").execute(self, list);
if (!result.fitsInDouble()) {
throw new AssertionError("Shall be a double: " + result);
}
var calculated = (long) result.asDouble();
var expected = 21;
if (calculated != expected) {
throw new AssertionError("Expected " + expected + " from sum but got " + calculated);
}
hole.consume(result);
var calculated = (long) result.asDouble();
var expected = 21;
if (calculated != expected) {
throw new AssertionError("Expected " + expected + " from sum but got " + calculated);
}
hole.consume(result);
}
}

View File

@ -1,11 +1,10 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.util.concurrent.TimeUnit;
import org.enso.interpreter.bench.fixtures.semantic.RecursionFixtures;
import org.enso.interpreter.test.DefaultInterpreterRunner;
import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@Fork(1)
@Warmup(iterations = 5)

View File

@ -1,15 +1,15 @@
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 org.graalvm.polyglot.Source;
import static org.junit.Assert.assertNotNull;
import org.openjdk.jmh.infra.BenchmarkParams;
final class SrcUtil {
private SrcUtil() {
}
private SrcUtil() {}
static String findName(BenchmarkParams params) {
return params.getBenchmark().replaceFirst(".*\\.", "");
@ -19,7 +19,7 @@ final class SrcUtil {
var d = new File(new File(new File("."), "target"), "bench-data");
d.mkdirs();
var f = new File(d, benchmarkName + ".enso");
try ( var w = new FileWriter(f)) {
try (var w = new FileWriter(f)) {
w.write(code);
}
return Source.newBuilder("enso", f).build();

View File

@ -1,11 +1,9 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.io.ByteArrayOutputStream;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.logging.Level;
import org.enso.polyglot.RuntimeOptions;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
@ -23,7 +21,6 @@ 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 = 3)
@ -37,21 +34,20 @@ public class StringBenchmarks {
@Setup
public void initializeBenchmark(BenchmarkParams params) throws Exception {
var ctx = Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(
RuntimeOptions.LOG_LEVEL,
Level.WARNING.getName()
)
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath()
).build();
var ctx =
Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath())
.build();
var code ="""
var code =
"""
from Standard.Base import all
all_length v = v.fold 0 (sum -> str -> sum + str.length)
@ -66,7 +62,7 @@ public class StringBenchmarks {
var module = ctx.eval(src);
this.self = module.invokeMember("get_associated_type");
Function<String,Value> getMethod = (name) -> module.invokeMember("get_method", self, name);
Function<String, Value> getMethod = (name) -> module.invokeMember("get_method", self, name);
var repeat = 2000;
var length = 1000;
@ -88,4 +84,3 @@ public class StringBenchmarks {
matter.consume(result);
}
}

View File

@ -1,5 +1,9 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.logging.Level;
import org.enso.polyglot.MethodNames.Module;
import org.enso.polyglot.RuntimeOptions;
import org.graalvm.polyglot.Context;
@ -9,13 +13,6 @@ import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.BenchmarkParams;
import org.openjdk.jmh.infra.Blackhole;
import java.io.ByteArrayOutputStream;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.logging.Level;
@BenchmarkMode(Mode.AverageTime)
@Fork(1)
@Warmup(iterations = 3)
@ -29,20 +26,19 @@ public class TypePatternBenchmarks {
@Setup
public void initializeBenchmark(BenchmarkParams params) throws Exception {
var ctx = Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(
RuntimeOptions.LOG_LEVEL,
Level.WARNING.getName()
)
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath()
).build();
var code ="""
var ctx =
Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath())
.build();
var code =
"""
from Standard.Base import Integer, Vector, Any, Float
avg arr =
@ -72,7 +68,7 @@ public class TypePatternBenchmarks {
var src = SrcUtil.source(benchmarkName, code);
var module = ctx.eval(src);
Function<String,Value> getMethod = (name) -> module.invokeMember(Module.EVAL_EXPRESSION, name);
Function<String, Value> getMethod = (name) -> module.invokeMember(Module.EVAL_EXPRESSION, name);
var length = 100;
this.vec = getMethod.apply("gen_vec").execute(length, 1.1);
@ -85,8 +81,9 @@ public class TypePatternBenchmarks {
}
/**
* Adding @ExplodeLoop in {@link org.enso.interpreter.node.controlflow.caseexpr.CatchTypeBranchNode} specialization
* decreases the performance of this benchmark.
* Adding @ExplodeLoop in {@link
* org.enso.interpreter.node.controlflow.caseexpr.CatchTypeBranchNode} specialization decreases
* the performance of this benchmark.
*/
@Benchmark
public void matchOverAny(Blackhole matter) {
@ -94,7 +91,8 @@ public class TypePatternBenchmarks {
}
/**
* Benchmark that matches over a Float. The old (decimal) name is kept to keep the history of results consistent.
* Benchmark that matches over a Float. The old (decimal) name is kept to keep the history of
* results consistent.
*/
@Benchmark
public void matchOverDecimal(Blackhole matter) {
@ -113,4 +111,3 @@ public class TypePatternBenchmarks {
matter.consume(result);
}
}

View File

@ -1,12 +1,10 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.io.ByteArrayOutputStream;
import java.nio.file.Paths;
import java.util.AbstractList;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.logging.Level;
import org.enso.polyglot.RuntimeOptions;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
@ -24,7 +22,6 @@ 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 = 3)
@ -38,22 +35,21 @@ public class VectorBenchmarks {
@Setup
public void initializeBenchmark(BenchmarkParams params) throws Exception {
var ctx = Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(
RuntimeOptions.LOG_LEVEL,
Level.WARNING.getName()
)
var ctx =
Context.newBuilder()
.allowExperimentalOptions(true)
.allowIO(IOAccess.ALL)
.allowAllAccess(true)
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
.logHandler(System.err)
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath()
).build();
.option(
"enso.languageHomeOverride",
Paths.get("../../distribution/component").toFile().getAbsolutePath())
.build();
var benchmarkName = SrcUtil.findName(params);
var code = """
var code =
"""
import Standard.Base.Data.Vector.Vector
import Standard.Base.Data.Array_Proxy.Array_Proxy
@ -89,49 +85,57 @@ public class VectorBenchmarks {
var module = ctx.eval(SrcUtil.source(benchmarkName, code));
this.self = module.invokeMember("get_associated_type");
Function<String,Value> getMethod = (name) -> module.invokeMember("get_method", self, name);
Function<String, Value> getMethod = (name) -> module.invokeMember("get_method", self, name);
var length = 1000;
Value vec = getMethod.apply("fibarr").execute(self, length, Integer.MAX_VALUE);
switch (benchmarkName) {
case "averageOverVector": {
this.arrayOfFibNumbers = vec;
break;
}
case "averageOverSlice": {
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, vec, 1, length);
break;
}
case "averageOverArray": {
this.arrayOfFibNumbers = getMethod.apply("to_array").execute(self, vec);
break;
}
case "averageOverPolyglotVector": {
long[] copy = copyToPolyglotArray(vec);
this.arrayOfFibNumbers = getMethod.apply("to_vector").execute(self, copy);
break;
}
case "averageOverPolyglotArray": {
long[] copy = copyToPolyglotArray(vec);
this.arrayOfFibNumbers = Value.asValue(copy);
break;
}
case "averageOverArrayProxy": {
this.arrayOfFibNumbers = getMethod.apply("create_array_proxy").execute(self, vec);
break;
}
case "averageOverArrayProxyNew": {
this.arrayOfFibNumbers = getMethod.apply("create_array_proxy_new").execute(self, vec);
break;
}
case "averageAbstractList": {
long[] copy = copyToPolyglotArray(vec);
final ProxyList<Long> proxyList = new ProxyList<Long>();
getMethod.apply("fill_proxy").execute(self, proxyList, copy);
this.arrayOfFibNumbers = Value.asValue(proxyList);
break;
}
case "averageOverVector":
{
this.arrayOfFibNumbers = vec;
break;
}
case "averageOverSlice":
{
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, vec, 1, length);
break;
}
case "averageOverArray":
{
this.arrayOfFibNumbers = getMethod.apply("to_array").execute(self, vec);
break;
}
case "averageOverPolyglotVector":
{
long[] copy = copyToPolyglotArray(vec);
this.arrayOfFibNumbers = getMethod.apply("to_vector").execute(self, copy);
break;
}
case "averageOverPolyglotArray":
{
long[] copy = copyToPolyglotArray(vec);
this.arrayOfFibNumbers = Value.asValue(copy);
break;
}
case "averageOverArrayProxy":
{
this.arrayOfFibNumbers = getMethod.apply("create_array_proxy").execute(self, vec);
break;
}
case "averageOverArrayProxyNew":
{
this.arrayOfFibNumbers = getMethod.apply("create_array_proxy_new").execute(self, vec);
break;
}
case "averageAbstractList":
{
long[] copy = copyToPolyglotArray(vec);
final ProxyList<Long> proxyList = new ProxyList<Long>();
getMethod.apply("fill_proxy").execute(self, proxyList, copy);
this.arrayOfFibNumbers = Value.asValue(proxyList);
break;
}
default:
throw new IllegalStateException("Unexpected benchmark: " + params.getBenchmark());
@ -193,9 +197,12 @@ public class VectorBenchmarks {
throw new AssertionError("Shall be a double: " + average);
}
var result = (long) average.asDouble();
boolean isResultCorrect = (result >= 1019950590 && result <= 1019950600) || (result >= 1020971561 && result <= 1020971571);
boolean isResultCorrect =
(result >= 1019950590 && result <= 1019950600)
|| (result >= 1020971561 && result <= 1020971571);
if (!isResultCorrect) {
throw new AssertionError("Expecting reasonable average but was " + result + "\n" + arrayOfFibNumbers);
throw new AssertionError(
"Expecting reasonable average but was " + result + "\n" + arrayOfFibNumbers);
}
hole.consume(result);
}
@ -220,4 +227,3 @@ public class VectorBenchmarks {
}
}
}

View File

@ -1,5 +1,11 @@
package org.enso.interpreter.bench.benchmarks.semantic;
import java.io.IOException;
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 org.enso.polyglot.MethodNames;
import org.graalvm.polyglot.Context;
@ -10,20 +16,13 @@ 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.Setup;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.BenchmarkParams;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@ -31,49 +30,52 @@ import java.util.concurrent.TimeUnit;
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
public class WarningBenchmarks extends TestBase {
private static final int INPUT_VEC_SIZE = 10_000;
private static final int INPUT_DIFF_VEC_SIZE = 10_000;
private Context ctx;
private Value vecSumBench;
private static final int INPUT_VEC_SIZE = 10_000;
private static final int INPUT_DIFF_VEC_SIZE = 10_000;
private Context ctx;
private Value vecSumBench;
private Value createVec;
private Value mapVecWithWarnings;
private Value noWarningsVec;
private Value sameWarningVec;
private Value randomVec;
private Value randomElemsWithWarningsVec;
private Value constElem;
private Value constElemWithWarning;
private Value createVec;
private Value mapVecWithWarnings;
private Value noWarningsVec;
private Value sameWarningVec;
private Value randomVec;
private Value randomElemsWithWarningsVec;
private Value constElem;
private Value constElemWithWarning;
private String benchmarkName;
private String benchmarkName;
private int randomVectorSum = 0;
private int randomVectorSum = 0;
private record GeneratedVector(StringBuilder repr, int sum) {}
private record GeneratedVector(StringBuilder repr, int sum) {}
private GeneratedVector generateRandomVector(Random random, String vectorName, long vectorSize, int maxRange) {
List<Integer> primitiveValues = new ArrayList<>();
random.ints(vectorSize, 0, maxRange).forEach(primitiveValues::add);
var sb = new StringBuilder();
sb.append(vectorName).append(" = [");
var sum = 0;
for (Integer intValue : primitiveValues) {
sb.append(intValue).append(",");
sum += Math.abs(intValue);
}
sb.setCharAt(sb.length() - 1, ']');
sb.append('\n');
return new GeneratedVector(sb, sum);
private GeneratedVector generateRandomVector(
Random random, String vectorName, long vectorSize, int maxRange) {
List<Integer> primitiveValues = new ArrayList<>();
random.ints(vectorSize, 0, maxRange).forEach(primitiveValues::add);
var sb = new StringBuilder();
sb.append(vectorName).append(" = [");
var sum = 0;
for (Integer intValue : primitiveValues) {
sb.append(intValue).append(",");
sum += Math.abs(intValue);
}
sb.setCharAt(sb.length() - 1, ']');
sb.append('\n');
return new GeneratedVector(sb, sum);
}
@Setup
public void initializeBench(BenchmarkParams params) throws IOException {
ctx = createDefaultContext();
var random = new Random(42);
@Setup
public void initializeBench(BenchmarkParams params) throws IOException {
ctx = createDefaultContext();
var random = new Random(42);
benchmarkName = SrcUtil.findName(params);
benchmarkName = SrcUtil.findName(params);
var code = new StringBuilder("""
var code =
new StringBuilder(
"""
from Standard.Base import all
vec_sum_bench : Vector Integer -> Integer
@ -82,10 +84,10 @@ public class WarningBenchmarks extends TestBase {
create_vec size elem =
Vector.fill size elem
elem =
42
elem_const_with_warning =
x = 42
Warning.attach "Foo!" x
@ -97,59 +99,69 @@ public class WarningBenchmarks extends TestBase {
vec.map (e-> elem_with_warning e)
""");
// generate random vector
var randomIntVectorName = "vector_with_random_values";
var vectorWithRandomValues = generateRandomVector(random, randomIntVectorName, INPUT_DIFF_VEC_SIZE, 3_000);
code.append(vectorWithRandomValues.repr());
randomVectorSum = vectorWithRandomValues.sum();
// generate random vector
var randomIntVectorName = "vector_with_random_values";
var vectorWithRandomValues =
generateRandomVector(random, randomIntVectorName, INPUT_DIFF_VEC_SIZE, 3_000);
code.append(vectorWithRandomValues.repr());
randomVectorSum = vectorWithRandomValues.sum();
var src = SrcUtil.source(benchmarkName, code.toString());
Value module = ctx.eval(src);
vecSumBench = Objects.requireNonNull(module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "vec_sum_bench"));
createVec = Objects.requireNonNull(module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create_vec"));
mapVecWithWarnings = Objects.requireNonNull(module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "map_vector_with_warnings"));
constElem = Objects.requireNonNull(module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "elem"));
constElemWithWarning = Objects.requireNonNull(module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "elem_const_with_warning"));
noWarningsVec = createVec.execute(INPUT_VEC_SIZE, constElem);
sameWarningVec = createVec.execute(INPUT_VEC_SIZE, constElemWithWarning);
randomVec = Objects.requireNonNull(module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, randomIntVectorName));
randomElemsWithWarningsVec = mapVecWithWarnings.execute(randomVec);
var src = SrcUtil.source(benchmarkName, code.toString());
Value module = ctx.eval(src);
vecSumBench =
Objects.requireNonNull(
module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "vec_sum_bench"));
createVec =
Objects.requireNonNull(
module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create_vec"));
mapVecWithWarnings =
Objects.requireNonNull(
module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "map_vector_with_warnings"));
constElem =
Objects.requireNonNull(module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "elem"));
constElemWithWarning =
Objects.requireNonNull(
module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "elem_const_with_warning"));
noWarningsVec = createVec.execute(INPUT_VEC_SIZE, constElem);
sameWarningVec = createVec.execute(INPUT_VEC_SIZE, constElemWithWarning);
randomVec =
Objects.requireNonNull(
module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, randomIntVectorName));
randomElemsWithWarningsVec = mapVecWithWarnings.execute(randomVec);
}
@TearDown
public void cleanup() {
ctx.close(true);
}
@Benchmark
public void noWarningsVecSum() {
Value res = vecSumBench.execute(noWarningsVec);
checkResult(res, INPUT_VEC_SIZE * 42);
}
@Benchmark
public void sameWarningVecSum() {
Value res = vecSumBench.execute(sameWarningVec);
checkResult(res, INPUT_VEC_SIZE * 42);
}
@Benchmark
public void randomElementsVecSum() {
Value res = vecSumBench.execute(randomVec);
checkResult(res, randomVectorSum);
}
@Benchmark
public void diffWarningRandomElementsVecSum() {
Value res = vecSumBench.execute(randomElemsWithWarningsVec);
checkResult(res, randomVectorSum);
}
private static void checkResult(Value res, int expected) {
if (res.asInt() != expected) {
throw new AssertionError("Expected result: " + INPUT_VEC_SIZE * 42 + ", got: " + res.asInt());
}
@TearDown
public void cleanup() {
ctx.close(true);
}
@Benchmark
public void noWarningsVecSum() {
Value res = vecSumBench.execute(noWarningsVec);
checkResult(res, INPUT_VEC_SIZE*42);
}
@Benchmark
public void sameWarningVecSum() {
Value res = vecSumBench.execute(sameWarningVec);
checkResult(res, INPUT_VEC_SIZE*42);
}
@Benchmark
public void randomElementsVecSum() {
Value res = vecSumBench.execute(randomVec);
checkResult(res, randomVectorSum);
}
@Benchmark
public void diffWarningRandomElementsVecSum() {
Value res = vecSumBench.execute(randomElemsWithWarningsVec);
checkResult(res, randomVectorSum);
}
private static void checkResult(Value res, int expected) {
if (res.asInt() != expected) {
throw new AssertionError("Expected result: " + INPUT_VEC_SIZE*42 + ", got: " + res.asInt());
}
}
}
}