-
Notifications
You must be signed in to change notification settings - Fork 326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial benchmarks for intersection types + a bit of speedup #11924
Changes from 5 commits
086d024
a33965d
171c799
775595c
e2760ff
630ec62
8defcfe
d44d30e
7b6d364
bda398a
56b24aa
2dcc2c4
ee080a3
53c2222
9567257
6bfdbf9
4dacf53
ebe0553
2301f9b
8d5452c
ed8799c
615b600
a68db22
98ebc39
a9f57f0
035b2be
3f0a3e3
9503f79
f515d8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package org.enso.interpreter.bench.benchmarks.semantic; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
import java.util.function.Function; | ||
import org.enso.compiler.benchmarks.Utils; | ||
import org.graalvm.polyglot.Value; | ||
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; | ||
|
||
/** | ||
* These benchmarks compare performance of {@link EnsoMultiValue}. They create a vector in a certain | ||
* configuration representing numbers and then they perform {@code sum} operation on it. | ||
*/ | ||
@BenchmarkMode(Mode.AverageTime) | ||
@Fork(1) | ||
@Warmup(iterations = 3) | ||
@Measurement(iterations = 5) | ||
@OutputTimeUnit(TimeUnit.MILLISECONDS) | ||
@State(Scope.Benchmark) | ||
public class MultiValueBenchmarks { | ||
private Value arrayOfNumbers; | ||
private Value sum; | ||
private Value self; | ||
private final long length = 100000; | ||
|
||
@Setup | ||
public void initializeBenchmark(BenchmarkParams params) throws Exception { | ||
var ctx = Utils.createDefaultContextBuilder().build(); | ||
var code = | ||
""" | ||
from Standard.Base import Vector, Float, Number, Integer | ||
|
||
type Complex | ||
private Number re:Float im:Float | ||
|
||
Complex.from (that:Number) = Complex.Number that 0 | ||
|
||
sum arr = | ||
go acc i = if i >= arr.length then acc else | ||
v = arr.at i : Float | ||
sum = acc + v | ||
@Tail_Call go sum i+1 | ||
go 0 0 | ||
|
||
|
||
make_vector type n = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A dedicated benchmark for
After 630ec62 the results are better:
and there are no bailouts. Time to really speed things up. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some speedup achieved... |
||
Vector.new n i-> | ||
r = 3 + 5*i | ||
case type of | ||
0 -> r:Integer | ||
1 -> r:Float | ||
2 -> r:Complex | ||
3 -> | ||
c = r:Complex&Float | ||
c:Float | ||
4 -> | ||
c = r:Float&Complex | ||
c:Float | ||
5 -> r:Complex&Float | ||
6 -> r:Float&Complex | ||
"""; | ||
var benchmarkName = SrcUtil.findName(params); | ||
var src = SrcUtil.source(benchmarkName, code); | ||
var module = ctx.eval(src); | ||
|
||
this.self = module.invokeMember("get_associated_type"); | ||
Function<String, Value> getMethod = (name) -> module.invokeMember("get_method", self, name); | ||
|
||
String test_builder; | ||
int type = Integer.parseInt(benchmarkName.substring(benchmarkName.length() - 1)); | ||
this.arrayOfNumbers = getMethod.apply("make_vector").execute(self, type, length); | ||
this.sum = getMethod.apply("sum"); | ||
} | ||
|
||
@Benchmark | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is now the base benchmark. The results after 4dacf53 are:
still 60 times slower than it should be. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The biggest slowdown is currently in It seems to always allocate new arrays. Rather it should treat Attempting to make things better in a follow up PR: |
||
public void sumOverInteger0(Blackhole matter) { | ||
performBenchmark(matter); | ||
} | ||
|
||
@Benchmark | ||
public void sumOverFloat1(Blackhole matter) { | ||
performBenchmark(matter); | ||
} | ||
|
||
@Benchmark | ||
public void sumOverComplexCast2(Blackhole matter) { | ||
performBenchmark(matter); | ||
} | ||
|
||
@Benchmark | ||
public void sumOverComplexFloatRecastedToFloat3(Blackhole matter) { | ||
performBenchmark(matter); | ||
} | ||
|
||
@Benchmark | ||
public void sumOverFloatComplexRecastedToFloat4(Blackhole matter) { | ||
performBenchmark(matter); | ||
} | ||
|
||
@Benchmark | ||
public void sumOverComplexAndFloat5(Blackhole matter) { | ||
performBenchmark(matter); | ||
} | ||
|
||
@Benchmark | ||
public void sumOverFloatAndComplex6(Blackhole matter) { | ||
performBenchmark(matter); | ||
} | ||
|
||
private void performBenchmark(Blackhole matter) throws AssertionError { | ||
var resultValue = sum.execute(self, arrayOfNumbers); | ||
if (!resultValue.fitsInLong()) { | ||
throw new AssertionError("Shall be a long: " + resultValue); | ||
} | ||
long result = resultValue.asLong(); | ||
long expectedResult = length * 3L + (5L * (length * (length - 1L) / 2L)); | ||
boolean isResultCorrect = result == expectedResult; | ||
if (!isResultCorrect) { | ||
throw new AssertionError("Expecting " + expectedResult + " but was " + result); | ||
} | ||
matter.consume(result); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Akirathan, @hubertp, @4e6 (and also @radeusgd):
Vector
is created bymake_vector typ
methodtyp
es includeInteger
,Float
,Complex
as non-intersection type benchmarks to compare totyp
es mixingFloat
andComplex
together into different intersection typesIdeally the intersection types benchmark results should be close to base benchmark
sumOverComplexBaseBenchmark0
with some "reasonable overhead".Are you OK with these benchmarks?