Skip to content

Commit 737d504

Browse files
author
Suszyński Krzysztof
committed
Performance test to compare agains Guava's Preconditions
1 parent 656f92a commit 737d504

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@
132132
<version>1.7.19</version>
133133
<scope>test</scope>
134134
</dependency>
135+
<dependency>
136+
<groupId>com.google.guava</groupId>
137+
<artifactId>guava</artifactId>
138+
<version>19.0</version>
139+
<scope>test</scope>
140+
</dependency>
135141

136142
</dependencies>
137143

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package pl.wavesoftware.eid.utils;
2+
3+
import com.google.common.base.Preconditions;
4+
import org.junit.ClassRule;
5+
import org.junit.Test;
6+
import org.openjdk.jmh.annotations.Benchmark;
7+
import org.openjdk.jmh.annotations.Mode;
8+
import org.openjdk.jmh.annotations.Threads;
9+
import org.openjdk.jmh.infra.Blackhole;
10+
import org.openjdk.jmh.results.RunResult;
11+
import org.openjdk.jmh.runner.Runner;
12+
import org.openjdk.jmh.runner.RunnerException;
13+
import org.openjdk.jmh.runner.options.Options;
14+
import org.openjdk.jmh.runner.options.OptionsBuilder;
15+
import org.openjdk.jmh.runner.options.TimeValue;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
18+
import pl.wavesoftware.eid.exceptions.EidRuntimeException;
19+
import pl.wavesoftware.testing.JmhCleaner;
20+
21+
import java.lang.annotation.ElementType;
22+
import java.lang.annotation.Retention;
23+
import java.lang.annotation.RetentionPolicy;
24+
import java.lang.annotation.Target;
25+
import java.lang.reflect.Method;
26+
import java.util.Collection;
27+
import java.util.concurrent.TimeUnit;
28+
29+
import static org.assertj.core.api.Assertions.assertThat;
30+
31+
/**
32+
* @author <a href="mailto:krzysztof.suszynski@coi.gov.pl">Krzysztof Suszynski</a>
33+
* @since 25.03.16
34+
*/
35+
public class EidPreconditionsIT {
36+
private static final int OPERATIONS = 1000;
37+
private static final double SPEED_THRESHOLD = 0.25;
38+
private static final Logger LOG = LoggerFactory.getLogger(EidPreconditionsIT.class);
39+
private static final double PERCENT = 100;
40+
41+
@ClassRule
42+
public static JmhCleaner cleaner = new JmhCleaner(EidPreconditionsIT.class);
43+
44+
@Test
45+
public void doBenchmarking() throws RunnerException {
46+
Options opt = new OptionsBuilder()
47+
.include(this.getClass().getName() + ".*")
48+
.mode(Mode.Throughput)
49+
.timeUnit(TimeUnit.MICROSECONDS)
50+
.operationsPerInvocation(OPERATIONS)
51+
.warmupTime(TimeValue.seconds(1))
52+
.warmupIterations(1)
53+
.measurementTime(TimeValue.seconds(1))
54+
.measurementIterations(3)
55+
.threads(Threads.MAX)
56+
.forks(1)
57+
.shouldFailOnError(true)
58+
.shouldDoGC(true)
59+
.build();
60+
61+
Runner runner = new Runner(opt);
62+
Collection<RunResult> results = runner.run();
63+
assertThat(results).hasSize(TestCase.values().length * 2);
64+
65+
verifySpeedFor(TestCase.CHECK_ARGUMENT, results);
66+
verifySpeedFor(TestCase.CHECK_STATE, results);
67+
verifySpeedFor(TestCase.CHECK_NOTNULL, results);
68+
}
69+
70+
@Benchmark
71+
@BenchmarkConfig(test = TestCase.CHECK_ARGUMENT, framework = Framework.GUAVA)
72+
public void testCheckArgument(Blackhole bh) {
73+
for (int i = 0; i < OPERATIONS; i++) {
74+
Preconditions.checkArgument(i >= 0, "20160325:123449");
75+
bh.consume(i);
76+
}
77+
}
78+
79+
@Benchmark
80+
@BenchmarkConfig(test = TestCase.CHECK_STATE, framework = Framework.GUAVA)
81+
public void testCheckState(Blackhole bh) {
82+
for (int i = 0; i < OPERATIONS; i++) {
83+
Preconditions.checkState(i >= 0, "20160325:123534");
84+
bh.consume(i);
85+
}
86+
}
87+
88+
@Benchmark
89+
@BenchmarkConfig(test = TestCase.CHECK_NOTNULL, framework = Framework.GUAVA)
90+
public void testCheckNotNull(Blackhole bh) {
91+
for (int i = 0; i < OPERATIONS; i++) {
92+
bh.consume(Preconditions.checkNotNull(bh, "20160325:123600"));
93+
}
94+
}
95+
96+
@Benchmark
97+
@BenchmarkConfig(test = TestCase.CHECK_ARGUMENT, framework = Framework.EID)
98+
public void testCheckArgumentEid(Blackhole bh) {
99+
for (int i = 0; i < OPERATIONS; i++) {
100+
EidPreconditions.checkArgument(i >= 0, "20160325:123701");
101+
bh.consume(i);
102+
}
103+
}
104+
105+
@Benchmark
106+
@BenchmarkConfig(test = TestCase.CHECK_STATE, framework = Framework.EID)
107+
public void testCheckStateEid(Blackhole bh) {
108+
for (int i = 0; i < OPERATIONS; i++) {
109+
EidPreconditions.checkState(i >= 0, "20160325:123705");
110+
bh.consume(i);
111+
}
112+
}
113+
114+
@Benchmark
115+
@BenchmarkConfig(test = TestCase.CHECK_NOTNULL, framework = Framework.EID)
116+
public void testCheckNotNullEid(Blackhole bh) {
117+
for (int i = 0; i < OPERATIONS; i++) {
118+
bh.consume(EidPreconditions.checkNotNull(bh, "20160325:123710"));
119+
}
120+
}
121+
122+
private void verifySpeedFor(TestCase testCase, Collection<RunResult> results) {
123+
Method guavaMethod = findMethod(testCase, Framework.GUAVA);
124+
Method eidMethod = findMethod(testCase, Framework.EID);
125+
126+
RunResult guavaResult = lookupResult(results, guavaMethod);
127+
RunResult eidResult = lookupResult(results, eidMethod);
128+
129+
double guava = getScore(guavaResult);
130+
double eid = getScore(eidResult);
131+
132+
double quotient = eid / guava;
133+
134+
LOG.info(String.format("%s: Guava score = %.2f vs Eid score = %.2f ==> quotient: %.2f%%, expected: %.2f%%",
135+
testCase, guava, eid, quotient * PERCENT, SPEED_THRESHOLD * PERCENT));
136+
assertThat(quotient).isGreaterThanOrEqualTo(SPEED_THRESHOLD);
137+
}
138+
139+
private static double getScore(RunResult result) {
140+
return result.getPrimaryResult().getScore();
141+
}
142+
143+
private RunResult lookupResult(Collection<RunResult> results, Method method) {
144+
String name = method.getName();
145+
String fullName = String.format("%s.%s", this.getClass().getName(), name);
146+
for (RunResult result : results) {
147+
if (result.getParams().getBenchmark().equals(fullName)) {
148+
return result;
149+
}
150+
}
151+
throw new EidRuntimeException("20160324:225412", "Invalid name: " + name);
152+
}
153+
154+
private Method findMethod(TestCase testCase, Framework framework) {
155+
for (Method method : this.getClass().getDeclaredMethods()) {
156+
BenchmarkConfig config = method.getAnnotation(BenchmarkConfig.class);
157+
if (config == null) {
158+
continue;
159+
}
160+
if (config.framework() == framework && config.test() == testCase) {
161+
return method;
162+
}
163+
}
164+
throw new IllegalArgumentException(String.format("No testCase: %s for framework: %s found!",
165+
testCase, framework));
166+
}
167+
168+
@Target(ElementType.METHOD)
169+
@Retention(RetentionPolicy.RUNTIME)
170+
private @interface BenchmarkConfig {
171+
TestCase test();
172+
Framework framework();
173+
}
174+
175+
private enum TestCase {
176+
CHECK_ARGUMENT,
177+
CHECK_STATE,
178+
CHECK_NOTNULL
179+
}
180+
181+
private enum Framework {
182+
GUAVA, EID
183+
}
184+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SLF4J's SimpleLogger configuration file
2+
org.slf4j.simpleLogger.defaultLogLevel=info
3+
org.slf4j.simpleLogger.showThreadName=false
4+
org.slf4j.simpleLogger.showLogName=false
5+
org.slf4j.simpleLogger.showShortLogName=false

0 commit comments

Comments
 (0)