Created
January 15, 2019 15:40
-
-
Save grondag/24667a1f3e57ad5e941df37b7d7714e9 to your computer and use it in GitHub Desktop.
Performance impact of instanceof test for interfaces
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=============================== | |
BENCHMARK CODE | |
=============================== | |
package grondag.benchmark; | |
import java.util.Random; | |
import org.openjdk.jmh.annotations.Benchmark; | |
public class InterfaceChecks { | |
public static interface Consistent { | |
boolean hasValue(); | |
int getValue(); | |
} | |
public static interface Inconsistent { | |
int getValue(); | |
} | |
// ensure we have a non-simple type hierarchy | |
public static interface NoiseA { } | |
public static interface NoiseB { } | |
public static interface NoiseC { } | |
public static interface NoiseD { } | |
public static interface NoiseE { } | |
public static class Missing implements Consistent, NoiseA, NoiseB, NoiseC, NoiseD, NoiseE { | |
@Override | |
public boolean hasValue() { | |
return false; | |
} | |
@Override | |
public int getValue() { | |
return 0; | |
} | |
} | |
public static class Present implements Consistent, Inconsistent, NoiseA, NoiseB, NoiseC, NoiseD, NoiseE { | |
final int value; | |
Present(int value) { | |
this.value = value; | |
} | |
@Override | |
public boolean hasValue() { | |
return true; | |
} | |
@Override | |
public int getValue() { | |
return value; | |
} | |
} | |
static final int SAMPLE_COUNT = 1000; | |
static final Object[] subjects = new Object[SAMPLE_COUNT]; | |
static { | |
Random r = new Random(); | |
for(int i = 0; i < SAMPLE_COUNT; i++) { | |
subjects[i] = r.nextBoolean() ? new Missing() : new Present(r.nextInt(0xFFFF)); | |
} | |
} | |
@Benchmark | |
public void testConsistent() { | |
int tally = 0; | |
for(Object o : subjects) { | |
Consistent c = (Consistent)o; | |
if(c.hasValue()) | |
tally += c.getValue(); | |
} | |
} | |
@Benchmark | |
public void testInconsistent() { | |
int tally = 0; | |
for(Object o : subjects) { | |
if(o instanceof Inconsistent) { | |
tally += ((Inconsistent)o).getValue(); | |
} | |
} | |
} | |
@Benchmark | |
public void testClass() { | |
int tally = 0; | |
for(Object o : subjects) { | |
if(o instanceof Present) { | |
tally += ((Present)o).getValue(); | |
} | |
} | |
} | |
} | |
=============================== | |
SUMMARY OF RESULTS | |
=============================== | |
Benchmark Mode Cnt Score Error Units | |
InterfaceChecks.testClass thrpt 25 1440402.994 ± 44639.119 ops/s | |
InterfaceChecks.testConsistent thrpt 25 920190.584 ± 17427.822 ops/s | |
InterfaceChecks.testInconsistent thrpt 25 78355.346 ± 1891.421 ops/s | |
=============================== | |
FULL JMH LOG BELOW | |
=============================== | |
# JMH version: 1.21 | |
# VM version: JDK 1.8.0_191, Java HotSpot(TM) 64-Bit Server VM, 25.191-b12 | |
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/bin/java | |
# VM options: <none> | |
# Warmup: 5 iterations, 10 s each | |
# Measurement: 5 iterations, 10 s each | |
# Timeout: 10 min per iteration | |
# Threads: 1 thread, will synchronize iterations | |
# Benchmark mode: Throughput, ops/time | |
# Benchmark: grondag.benchmark.InterfaceChecks.testClass | |
# Run progress: 0.00% complete, ETA 00:25:00 | |
# Fork: 1 of 5 | |
# Warmup Iteration 1: 1630623.845 ops/s | |
# Warmup Iteration 2: 1630506.649 ops/s | |
# Warmup Iteration 3: 1463384.640 ops/s | |
# Warmup Iteration 4: 1466727.271 ops/s | |
# Warmup Iteration 5: 1450841.079 ops/s | |
Iteration 1: 1455519.482 ops/s | |
Iteration 2: 1449128.299 ops/s | |
Iteration 3: 1414315.659 ops/s | |
Iteration 4: 1397652.587 ops/s | |
Iteration 5: 1348696.743 ops/s | |
# Run progress: 6.67% complete, ETA 00:23:27 | |
# Fork: 2 of 5 | |
# Warmup Iteration 1: 1582942.646 ops/s | |
# Warmup Iteration 2: 1631141.987 ops/s | |
# Warmup Iteration 3: 1494150.366 ops/s | |
# Warmup Iteration 4: 1511661.779 ops/s | |
# Warmup Iteration 5: 1512708.516 ops/s | |
Iteration 1: 1514950.888 ops/s | |
Iteration 2: 1507328.824 ops/s | |
Iteration 3: 1511371.008 ops/s | |
Iteration 4: 1509914.020 ops/s | |
Iteration 5: 1498794.563 ops/s | |
# Run progress: 13.33% complete, ETA 00:21:45 | |
# Fork: 3 of 5 | |
# Warmup Iteration 1: 1697489.017 ops/s | |
# Warmup Iteration 2: 1692034.364 ops/s | |
# Warmup Iteration 3: 1483670.314 ops/s | |
# Warmup Iteration 4: 1487860.956 ops/s | |
# Warmup Iteration 5: 1481181.576 ops/s | |
Iteration 1: 1485592.989 ops/s | |
Iteration 2: 1486233.110 ops/s | |
Iteration 3: 1443420.813 ops/s | |
Iteration 4: 1416856.214 ops/s | |
Iteration 5: 1362707.983 ops/s | |
# Run progress: 20.00% complete, ETA 00:20:05 | |
# Fork: 4 of 5 | |
# Warmup Iteration 1: 1494000.800 ops/s | |
# Warmup Iteration 2: 1649594.026 ops/s | |
# Warmup Iteration 3: 1452761.885 ops/s | |
# Warmup Iteration 4: 1469149.768 ops/s | |
# Warmup Iteration 5: 1457864.766 ops/s | |
Iteration 1: 1460998.046 ops/s | |
Iteration 2: 1332771.586 ops/s | |
Iteration 3: 1368607.534 ops/s | |
Iteration 4: 1420231.827 ops/s | |
Iteration 5: 1480091.124 ops/s | |
# Run progress: 26.67% complete, ETA 00:18:24 | |
# Fork: 5 of 5 | |
# Warmup Iteration 1: 1681607.564 ops/s | |
# Warmup Iteration 2: 1636520.395 ops/s | |
# Warmup Iteration 3: 1480012.014 ops/s | |
# Warmup Iteration 4: 1493619.722 ops/s | |
# Warmup Iteration 5: 1479310.614 ops/s | |
Iteration 1: 1349769.994 ops/s | |
Iteration 2: 1357899.966 ops/s | |
Iteration 3: 1449685.790 ops/s | |
Iteration 4: 1493087.450 ops/s | |
Iteration 5: 1494448.359 ops/s | |
Result "grondag.benchmark.InterfaceChecks.testClass": | |
1440402.994 ±(99.9%) 44639.119 ops/s [Average] | |
(min, avg, max) = (1332771.586, 1440402.994, 1514950.888), stdev = 59591.947 | |
CI (99.9%): [1395763.875, 1485042.114] (assumes normal distribution) | |
# JMH version: 1.21 | |
# VM version: JDK 1.8.0_191, Java HotSpot(TM) 64-Bit Server VM, 25.191-b12 | |
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/bin/java | |
# VM options: <none> | |
# Warmup: 5 iterations, 10 s each | |
# Measurement: 5 iterations, 10 s each | |
# Timeout: 10 min per iteration | |
# Threads: 1 thread, will synchronize iterations | |
# Benchmark mode: Throughput, ops/time | |
# Benchmark: grondag.benchmark.InterfaceChecks.testConsistent | |
# Run progress: 33.33% complete, ETA 00:16:44 | |
# Fork: 1 of 5 | |
# Warmup Iteration 1: 785784.019 ops/s | |
# Warmup Iteration 2: 961959.554 ops/s | |
# Warmup Iteration 3: 910328.606 ops/s | |
# Warmup Iteration 4: 936844.036 ops/s | |
# Warmup Iteration 5: 929185.069 ops/s | |
Iteration 1: 954587.862 ops/s | |
Iteration 2: 954112.598 ops/s | |
Iteration 3: 934940.749 ops/s | |
Iteration 4: 958569.235 ops/s | |
Iteration 5: 933260.347 ops/s | |
# Run progress: 40.00% complete, ETA 00:15:03 | |
# Fork: 2 of 5 | |
# Warmup Iteration 1: 799685.606 ops/s | |
# Warmup Iteration 2: 1018425.443 ops/s | |
# Warmup Iteration 3: 910837.958 ops/s | |
# Warmup Iteration 4: 914433.033 ops/s | |
# Warmup Iteration 5: 885393.282 ops/s | |
Iteration 1: 925166.525 ops/s | |
Iteration 2: 941484.456 ops/s | |
Iteration 3: 915567.910 ops/s | |
Iteration 4: 897602.584 ops/s | |
Iteration 5: 877910.785 ops/s | |
# Run progress: 46.67% complete, ETA 00:13:23 | |
# Fork: 3 of 5 | |
# Warmup Iteration 1: 792533.813 ops/s | |
# Warmup Iteration 2: 975762.130 ops/s | |
# Warmup Iteration 3: 917601.223 ops/s | |
# Warmup Iteration 4: 930877.084 ops/s | |
# Warmup Iteration 5: 887446.064 ops/s | |
Iteration 1: 887397.975 ops/s | |
Iteration 2: 892959.569 ops/s | |
Iteration 3: 881490.220 ops/s | |
Iteration 4: 894520.778 ops/s | |
Iteration 5: 930129.628 ops/s | |
# Run progress: 53.33% complete, ETA 00:11:43 | |
# Fork: 4 of 5 | |
# Warmup Iteration 1: 786687.551 ops/s | |
# Warmup Iteration 2: 975318.591 ops/s | |
# Warmup Iteration 3: 917360.402 ops/s | |
# Warmup Iteration 4: 912161.473 ops/s | |
# Warmup Iteration 5: 918204.740 ops/s | |
Iteration 1: 949386.870 ops/s | |
Iteration 2: 945608.375 ops/s | |
Iteration 3: 913853.691 ops/s | |
Iteration 4: 912815.539 ops/s | |
Iteration 5: 929787.543 ops/s | |
# Run progress: 60.00% complete, ETA 00:10:02 | |
# Fork: 5 of 5 | |
# Warmup Iteration 1: 816396.098 ops/s | |
# Warmup Iteration 2: 998544.413 ops/s | |
# Warmup Iteration 3: 912174.150 ops/s | |
# Warmup Iteration 4: 897145.230 ops/s | |
# Warmup Iteration 5: 929744.199 ops/s | |
Iteration 1: 922648.826 ops/s | |
Iteration 2: 913931.579 ops/s | |
Iteration 3: 914993.451 ops/s | |
Iteration 4: 911513.370 ops/s | |
Iteration 5: 910524.140 ops/s | |
Result "grondag.benchmark.InterfaceChecks.testConsistent": | |
920190.584 ±(99.9%) 17427.822 ops/s [Average] | |
(min, avg, max) = (877910.785, 920190.584, 958569.235), stdev = 23265.643 | |
CI (99.9%): [902762.763, 937618.406] (assumes normal distribution) | |
# JMH version: 1.21 | |
# VM version: JDK 1.8.0_191, Java HotSpot(TM) 64-Bit Server VM, 25.191-b12 | |
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/bin/java | |
# VM options: <none> | |
# Warmup: 5 iterations, 10 s each | |
# Measurement: 5 iterations, 10 s each | |
# Timeout: 10 min per iteration | |
# Threads: 1 thread, will synchronize iterations | |
# Benchmark mode: Throughput, ops/time | |
# Benchmark: grondag.benchmark.InterfaceChecks.testInconsistent | |
# Run progress: 66.67% complete, ETA 00:08:22 | |
# Fork: 1 of 5 | |
# Warmup Iteration 1: 76825.050 ops/s | |
# Warmup Iteration 2: 75448.191 ops/s | |
# Warmup Iteration 3: 78273.791 ops/s | |
# Warmup Iteration 4: 78163.358 ops/s | |
# Warmup Iteration 5: 78116.222 ops/s | |
Iteration 1: 77684.022 ops/s | |
Iteration 2: 73743.157 ops/s | |
Iteration 3: 73493.509 ops/s | |
Iteration 4: 75701.889 ops/s | |
Iteration 5: 77700.863 ops/s | |
# Run progress: 73.33% complete, ETA 00:06:41 | |
# Fork: 2 of 5 | |
# Warmup Iteration 1: 78216.680 ops/s | |
# Warmup Iteration 2: 78991.639 ops/s | |
# Warmup Iteration 3: 80136.113 ops/s | |
# Warmup Iteration 4: 77828.156 ops/s | |
# Warmup Iteration 5: 75594.921 ops/s | |
Iteration 1: 75836.032 ops/s | |
Iteration 2: 75886.783 ops/s | |
Iteration 3: 77409.299 ops/s | |
Iteration 4: 75828.263 ops/s | |
Iteration 5: 77795.896 ops/s | |
# Run progress: 80.00% complete, ETA 00:05:01 | |
# Fork: 3 of 5 | |
# Warmup Iteration 1: 74828.381 ops/s | |
# Warmup Iteration 2: 72187.938 ops/s | |
# Warmup Iteration 3: 78361.617 ops/s | |
# Warmup Iteration 4: 77345.074 ops/s | |
# Warmup Iteration 5: 80323.474 ops/s | |
Iteration 1: 80022.827 ops/s | |
Iteration 2: 79502.978 ops/s | |
Iteration 3: 79895.515 ops/s | |
Iteration 4: 79713.714 ops/s | |
Iteration 5: 79193.585 ops/s | |
# Run progress: 86.67% complete, ETA 00:03:20 | |
# Fork: 4 of 5 | |
# Warmup Iteration 1: 79364.627 ops/s | |
# Warmup Iteration 2: 76557.442 ops/s | |
# Warmup Iteration 3: 77653.180 ops/s | |
# Warmup Iteration 4: 78363.582 ops/s | |
# Warmup Iteration 5: 78482.792 ops/s | |
Iteration 1: 78698.569 ops/s | |
Iteration 2: 80083.003 ops/s | |
Iteration 3: 77701.191 ops/s | |
Iteration 4: 80101.058 ops/s | |
Iteration 5: 81821.293 ops/s | |
# Run progress: 93.33% complete, ETA 00:01:40 | |
# Fork: 5 of 5 | |
# Warmup Iteration 1: 78067.797 ops/s | |
# Warmup Iteration 2: 77887.662 ops/s | |
# Warmup Iteration 3: 80283.382 ops/s | |
# Warmup Iteration 4: 79995.244 ops/s | |
# Warmup Iteration 5: 80370.876 ops/s | |
Iteration 1: 82932.753 ops/s | |
Iteration 2: 80309.037 ops/s | |
Iteration 3: 75878.677 ops/s | |
Iteration 4: 82964.102 ops/s | |
Iteration 5: 78985.625 ops/s | |
Result "grondag.benchmark.InterfaceChecks.testInconsistent": | |
78355.346 ±(99.9%) 1891.421 ops/s [Average] | |
(min, avg, max) = (73493.509, 78355.346, 82964.102), stdev = 2524.993 | |
CI (99.9%): [76463.925, 80246.767] (assumes normal distribution) | |
# Run complete. Total time: 00:25:05 | |
REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on | |
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial | |
experiments, perform baseline and negative tests that provide experimental control, make sure | |
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts. | |
Do not assume the numbers tell you what you want them to tell. | |
Benchmark Mode Cnt Score Error Units | |
InterfaceChecks.testClass thrpt 25 1440402.994 ± 44639.119 ops/s | |
InterfaceChecks.testConsistent thrpt 25 920190.584 ± 17427.822 ops/s | |
InterfaceChecks.testInconsistent thrpt 25 78355.346 ± 1891.421 ops/s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment