Skip to content

Commit b759d75

Browse files
Multiple Vector.slice over each other slow things down (#11945)
Fixes #11859 by unwrapping results of previous `Vector.slice` before doing another `slice`.
1 parent dee53b7 commit b759d75

File tree

2 files changed

+51
-13
lines changed
  • engine

2 files changed

+51
-13
lines changed

engine/runtime-benchmarks/src/main/java/org/enso/interpreter/bench/benchmarks/semantic/VectorBenchmarks.java

+37-7
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020

2121
@BenchmarkMode(Mode.AverageTime)
2222
@Fork(1)
23-
@Warmup(iterations = 3)
24-
@Measurement(iterations = 5)
23+
@Warmup(iterations = 3, time = 3, timeUnit = TimeUnit.SECONDS)
24+
@Measurement(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)
2525
@OutputTimeUnit(TimeUnit.MILLISECONDS)
2626
@State(Scope.Benchmark)
2727
public class VectorBenchmarks {
@@ -35,10 +35,8 @@ public void initializeBenchmark(BenchmarkParams params) throws Exception {
3535
var benchmarkName = SrcUtil.findName(params);
3636
var code =
3737
"""
38-
import Standard.Base.Data.Vector.Builder
39-
import Standard.Base.Data.Vector.Vector
38+
from Standard.Base import all
4039
import Standard.Base.Data.Array_Proxy.Array_Proxy
41-
from Standard.Base.Data.Boolean import False
4240
4341
avg arr =
4442
sum acc i =
@@ -62,7 +60,16 @@ public void initializeBenchmark(BenchmarkParams params) throws Exception {
6260
6361
to_vector arr = Vector.from_polyglot_array arr
6462
to_array vec = vec.to_array
65-
slice vec = vec.slice
63+
slice n vec start end =
64+
initial = vec.slice start end
65+
66+
complicate round v = if round != 0 then complicate round-1 (v.slice 1 v.length) else
67+
Runtime.assert v==initial
68+
v
69+
70+
if n==0 then initial else
71+
complicate n (0.up_to n).to_vector+initial
72+
6673
fill_proxy proxy vec =
6774
size v =
6875
_ = v
@@ -91,7 +98,17 @@ public void initializeBenchmark(BenchmarkParams params) throws Exception {
9198
}
9299
case "averageOverSlice":
93100
{
94-
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, vec, 1, length);
101+
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, 0, vec, 1, length);
102+
break;
103+
}
104+
case "averageOverSliceWrapped10":
105+
{
106+
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, 10, vec, 1, length);
107+
break;
108+
}
109+
case "averageOverSliceWrapped100":
110+
{
111+
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, 100, vec, 1, length);
95112
break;
96113
}
97114
case "averageOverArray":
@@ -149,11 +166,24 @@ public void averageOverVector(Blackhole matter) {
149166
performBenchmark(matter);
150167
}
151168

169+
/** Measures performance of a single {@code Vector.slice}. */
152170
@Benchmark
153171
public void averageOverSlice(Blackhole matter) {
154172
performBenchmark(matter);
155173
}
156174

175+
/** Measures performance of {@code Vector.slice} applied ten times on the same array. */
176+
@Benchmark
177+
public void averageOverSliceWrapped10(Blackhole matter) {
178+
performBenchmark(matter);
179+
}
180+
181+
/** Measures performance of {@code Vector.slice} applied hundred times on the same array. */
182+
@Benchmark
183+
public void averageOverSliceWrapped100(Blackhole matter) {
184+
performBenchmark(matter);
185+
}
186+
157187
@Benchmark
158188
public void averageOverPolyglotVector(Blackhole matter) {
159189
performBenchmark(matter);

engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/ArraySlice.java

+14-6
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,34 @@ final class ArraySlice extends EnsoObject {
2929
private final long start;
3030
private final long end;
3131

32-
private ArraySlice(Object storage, long start, long end) {
33-
if (storage instanceof ArraySlice slice) {
32+
private ArraySlice(Object base, long start, long end) {
33+
var s = findStorage(base);
34+
if (s instanceof ArraySlice slice) {
3435
this.storage = slice.storage;
3536
this.start = slice.start + start;
3637
this.end = Math.min(slice.end, slice.start + end);
3738
} else {
3839
if (CompilerDirectives.inInterpreter()) {
39-
if (!InteropLibrary.getUncached().hasArrayElements(storage)) {
40+
if (!InteropLibrary.getUncached().hasArrayElements(s)) {
4041
throw EnsoContext.get(null)
4142
.raiseAssertionPanic(
42-
null, "ArraySlice needs array-like delegate, but got: " + storage, null);
43+
null, "ArraySlice needs array-like delegate, but got: " + s, null);
4344
}
4445
}
45-
46-
this.storage = storage;
46+
this.storage = s;
4747
this.start = start;
4848
this.end = end;
4949
}
5050
}
5151

52+
private static Object findStorage(Object storage) {
53+
return switch (storage) {
54+
case Vector.Generic gen -> gen.toArray();
55+
case ArraySlice slice -> slice;
56+
default -> storage;
57+
};
58+
}
59+
5260
static Vector createOrNull(Object storage, long start, long this_length, long end) {
5361
long slice_start = Math.max(0, start);
5462
long slice_end = Math.min(this_length, end);

0 commit comments

Comments
 (0)