Skip to content

Commit

Permalink
Multiple Vector.slice over each other slow things down (#11945)
Browse files Browse the repository at this point in the history
Fixes #11859 by unwrapping results of previous `Vector.slice` before doing another `slice`.
  • Loading branch information
JaroslavTulach authored Jan 4, 2025
1 parent dee53b7 commit b759d75
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@

@BenchmarkMode(Mode.AverageTime)
@Fork(1)
@Warmup(iterations = 3)
@Measurement(iterations = 5)
@Warmup(iterations = 3, time = 3, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
public class VectorBenchmarks {
Expand All @@ -35,10 +35,8 @@ public void initializeBenchmark(BenchmarkParams params) throws Exception {
var benchmarkName = SrcUtil.findName(params);
var code =
"""
import Standard.Base.Data.Vector.Builder
import Standard.Base.Data.Vector.Vector
from Standard.Base import all
import Standard.Base.Data.Array_Proxy.Array_Proxy
from Standard.Base.Data.Boolean import False
avg arr =
sum acc i =
Expand All @@ -62,7 +60,16 @@ public void initializeBenchmark(BenchmarkParams params) throws Exception {
to_vector arr = Vector.from_polyglot_array arr
to_array vec = vec.to_array
slice vec = vec.slice
slice n vec start end =
initial = vec.slice start end
complicate round v = if round != 0 then complicate round-1 (v.slice 1 v.length) else
Runtime.assert v==initial
v
if n==0 then initial else
complicate n (0.up_to n).to_vector+initial
fill_proxy proxy vec =
size v =
_ = v
Expand Down Expand Up @@ -91,7 +98,17 @@ public void initializeBenchmark(BenchmarkParams params) throws Exception {
}
case "averageOverSlice":
{
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, vec, 1, length);
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, 0, vec, 1, length);
break;
}
case "averageOverSliceWrapped10":
{
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, 10, vec, 1, length);
break;
}
case "averageOverSliceWrapped100":
{
this.arrayOfFibNumbers = getMethod.apply("slice").execute(self, 100, vec, 1, length);
break;
}
case "averageOverArray":
Expand Down Expand Up @@ -149,11 +166,24 @@ public void averageOverVector(Blackhole matter) {
performBenchmark(matter);
}

/** Measures performance of a single {@code Vector.slice}. */
@Benchmark
public void averageOverSlice(Blackhole matter) {
performBenchmark(matter);
}

/** Measures performance of {@code Vector.slice} applied ten times on the same array. */
@Benchmark
public void averageOverSliceWrapped10(Blackhole matter) {
performBenchmark(matter);
}

/** Measures performance of {@code Vector.slice} applied hundred times on the same array. */
@Benchmark
public void averageOverSliceWrapped100(Blackhole matter) {
performBenchmark(matter);
}

@Benchmark
public void averageOverPolyglotVector(Blackhole matter) {
performBenchmark(matter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,34 @@ final class ArraySlice extends EnsoObject {
private final long start;
private final long end;

private ArraySlice(Object storage, long start, long end) {
if (storage instanceof ArraySlice slice) {
private ArraySlice(Object base, long start, long end) {
var s = findStorage(base);
if (s instanceof ArraySlice slice) {
this.storage = slice.storage;
this.start = slice.start + start;
this.end = Math.min(slice.end, slice.start + end);
} else {
if (CompilerDirectives.inInterpreter()) {
if (!InteropLibrary.getUncached().hasArrayElements(storage)) {
if (!InteropLibrary.getUncached().hasArrayElements(s)) {
throw EnsoContext.get(null)
.raiseAssertionPanic(
null, "ArraySlice needs array-like delegate, but got: " + storage, null);
null, "ArraySlice needs array-like delegate, but got: " + s, null);
}
}

this.storage = storage;
this.storage = s;
this.start = start;
this.end = end;
}
}

private static Object findStorage(Object storage) {
return switch (storage) {
case Vector.Generic gen -> gen.toArray();
case ArraySlice slice -> slice;
default -> storage;
};
}

static Vector createOrNull(Object storage, long start, long this_length, long end) {
long slice_start = Math.max(0, start);
long slice_end = Math.min(this_length, end);
Expand Down

0 comments on commit b759d75

Please sign in to comment.