diff --git a/pom.xml b/pom.xml index f534f2a..eb957db 100644 --- a/pom.xml +++ b/pom.xml @@ -54,8 +54,8 @@ org.apache.maven.plugins maven-compiler-plugin - 19 - 19 + 21 + 21 diff --git a/src/main/java/red/hat/puzzles/polymorphism/TypeSwitchScalabilityBenchmark.java b/src/main/java/red/hat/puzzles/polymorphism/TypeSwitchScalabilityBenchmark.java new file mode 100644 index 0000000..360a4a7 --- /dev/null +++ b/src/main/java/red/hat/puzzles/polymorphism/TypeSwitchScalabilityBenchmark.java @@ -0,0 +1,98 @@ +package red.hat.puzzles.polymorphism; + +import org.openjdk.jmh.annotations.*; + +import java.io.Serializable; +import java.util.concurrent.TimeUnit; +import java.util.function.IntSupplier; + +@State(Scope.Benchmark) +@Measurement(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS) +@Warmup(iterations = 15, time = 200, timeUnit = TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Fork(2) +public class TypeSwitchScalabilityBenchmark { + + private static final class SerializableIntGarbage implements IntSupplier, Serializable { + private final int value; + + public SerializableIntGarbage(int value) { + this.value = value; + } + + @Override + public int getAsInt() { + return value; + } + } + + private static final class SerializableInt implements IntSupplier, Serializable { + private final int value; + + public SerializableInt(int value) { + this.value = value; + } + + @Override + public int getAsInt() { + return value; + } + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + private static boolean serialize(Serializable o) { + // NO-OP, we live dangerously here :P + return true; + } + + static boolean serialize(Object o) { + return switch (o) { + case Serializable value -> serialize(value); + default -> false; + }; + } + + static int getAsInt(Object o) { + return switch (o) { + case IntSupplier value -> value.getAsInt(); + default -> -1; + }; + } + + private Object o; + @Param({"false", "true"}) + private boolean typePollution; + + @Setup + public void init() { + if (typePollution) { + o = new SerializableIntGarbage(0); + for (int i = 0; i < 11000; i++) { + doSerialize(); + doGetAsInt(); + } + o = new SerializableInt(0); + for (int i = 0; i < 11000; i++) { + doSerialize(); + doGetAsInt(); + } + } + o = new SerializableInt(0); + + } + + @Benchmark + @Group + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public boolean doSerialize() { + return serialize(o); + } + + @Benchmark + @Group + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public int doGetAsInt() { + return getAsInt(o); + } + +}