8342540: InterfaceCalls micro-benchmark gives misleading results

Reviewed-by: shade, kvn
This commit is contained in:
Andrew Haley 2024-11-06 17:52:07 +00:00
parent c0e6c3b93c
commit 78b378ad03

View File

@ -29,6 +29,7 @@ import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.State;
@ -45,6 +46,11 @@ import java.util.concurrent.TimeUnit;
@Fork(value = 3) @Fork(value = 3)
public class InterfaceCalls { public class InterfaceCalls {
// Whether to step iteratively through the list of interfaces, or
// to select one in an unpredictable way.
@Param({"false", "true"})
private boolean randomized;
interface FirstInterface { interface FirstInterface {
public int getIntFirst(); public int getIntFirst();
} }
@ -241,44 +247,54 @@ public class InterfaceCalls {
*/ */
@Benchmark @Benchmark
public int test1stInt2Types() { public int test1stInt2Types() {
FirstInterface ai = as[l]; FirstInterface ai = as[step(2)];
l = 1 - l;
return ai.getIntFirst(); return ai.getIntFirst();
} }
@Benchmark @Benchmark
public int test1stInt3Types() { public int test1stInt3Types() {
FirstInterface ai = as[l]; FirstInterface ai = as[step(3)];
l = ++ l % 3;
return ai.getIntFirst(); return ai.getIntFirst();
} }
@Benchmark @Benchmark
public int test1stInt5Types() { public int test1stInt5Types() {
FirstInterface ai = as[l]; FirstInterface ai = as[step(asLength)];
l = ++ l % asLength;
return ai.getIntFirst(); return ai.getIntFirst();
} }
@Benchmark @Benchmark
public int test2ndInt2Types() { public int test2ndInt2Types() {
SecondInterface ai = (SecondInterface) as[l]; SecondInterface ai = (SecondInterface) as[step(2)];
l = 1 - l;
return ai.getIntSecond(); return ai.getIntSecond();
} }
@Benchmark @Benchmark
public int test2ndInt3Types() { public int test2ndInt3Types() {
SecondInterface ai = (SecondInterface) as[l]; SecondInterface ai = (SecondInterface) as[step(3)];
l = ++ l % 3;
return ai.getIntSecond(); return ai.getIntSecond();
} }
@Benchmark @Benchmark
public int test2ndInt5Types() { public int test2ndInt5Types() {
SecondInterface ai = (SecondInterface) as[l]; SecondInterface ai = (SecondInterface) as[step(asLength)];
l = ++ l % asLength;
return ai.getIntSecond(); return ai.getIntSecond();
} }
int step(int range) {
if (randomized) {
l = scramble(l);
} else {
l++;
}
return (l & Integer.MAX_VALUE) % range;
}
static final int scramble(int n) {
int x = n;
x ^= x << 13;
x ^= x >>> 17;
x ^= x << 5;
return x == 0 ? 1 : x;
}
} }