Skip to content

Commit 4d817c2

Browse files
authored
Merge pull request #3492 from graphql-java/cf-benchmark
A CompleteableFuture benchmark
2 parents 4307b3f + 99115a0 commit 4d817c2

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package benchmark;
2+
3+
import com.google.common.collect.ImmutableList;
4+
import org.openjdk.jmh.annotations.Benchmark;
5+
import org.openjdk.jmh.annotations.BenchmarkMode;
6+
import org.openjdk.jmh.annotations.Fork;
7+
import org.openjdk.jmh.annotations.Level;
8+
import org.openjdk.jmh.annotations.Measurement;
9+
import org.openjdk.jmh.annotations.Mode;
10+
import org.openjdk.jmh.annotations.Param;
11+
import org.openjdk.jmh.annotations.Scope;
12+
import org.openjdk.jmh.annotations.Setup;
13+
import org.openjdk.jmh.annotations.State;
14+
import org.openjdk.jmh.annotations.Warmup;
15+
import org.openjdk.jmh.runner.Runner;
16+
import org.openjdk.jmh.runner.options.Options;
17+
import org.openjdk.jmh.runner.options.OptionsBuilder;
18+
19+
import java.util.Collections;
20+
import java.util.List;
21+
import java.util.concurrent.CompletableFuture;
22+
23+
@State(Scope.Benchmark)
24+
@Warmup(iterations = 2, time = 1)
25+
@Measurement(iterations = 3, time = 10, batchSize = 10)
26+
@Fork(3)
27+
public class CompletableFuturesBenchmark {
28+
29+
30+
@Param({"2", "5"})
31+
public int depth;
32+
public int howMany = 10;
33+
34+
@Setup(Level.Trial)
35+
public void setUp() {
36+
}
37+
38+
private List<CompletableFuture<Object>> mkCFObjects(int howMany, int depth) {
39+
if (depth <= 0) {
40+
return Collections.emptyList();
41+
}
42+
ImmutableList.Builder<CompletableFuture<Object>> builder = ImmutableList.builder();
43+
for (int i = 0; i < howMany; i++) {
44+
CompletableFuture<Object> cf = CompletableFuture.completedFuture(mkCFObjects(howMany, depth - 1));
45+
builder.add(cf);
46+
}
47+
return builder.build();
48+
}
49+
50+
private List<Object> mkObjects(int howMany, int depth) {
51+
if (depth <= 0) {
52+
return Collections.emptyList();
53+
}
54+
ImmutableList.Builder<Object> builder = ImmutableList.builder();
55+
for (int i = 0; i < howMany; i++) {
56+
Object obj = mkObjects(howMany, depth - 1);
57+
builder.add(obj);
58+
}
59+
return builder.build();
60+
}
61+
62+
@Benchmark
63+
@BenchmarkMode(Mode.Throughput)
64+
public void benchmarkCFApproach() {
65+
// make results
66+
List<CompletableFuture<Object>> completableFutures = mkCFObjects(howMany, depth);
67+
// traverse results
68+
traverseCFS(completableFutures);
69+
}
70+
71+
@Benchmark
72+
@BenchmarkMode(Mode.Throughput)
73+
public void benchmarkMaterializedApproach() {
74+
// make results
75+
List<Object> objects = mkObjects(howMany, depth);
76+
// traverse results
77+
traverseObjects(objects);
78+
}
79+
80+
@SuppressWarnings("unchecked")
81+
private void traverseCFS(List<CompletableFuture<Object>> completableFutures) {
82+
for (CompletableFuture<Object> completableFuture : completableFutures) {
83+
// and when it's done - visit its child results - which are always immediate on completed CFs
84+
// so this whenComplete executed now
85+
completableFuture.whenComplete((list, t) -> {
86+
List<CompletableFuture<Object>> cfs = (List<CompletableFuture<Object>>) list;
87+
traverseCFS(cfs);
88+
});
89+
}
90+
}
91+
92+
@SuppressWarnings("unchecked")
93+
private void traverseObjects(List<Object> objects) {
94+
for (Object object : objects) {
95+
List<Object> list = (List<Object>) object;
96+
traverseObjects(list);
97+
}
98+
}
99+
100+
public static void main(String[] args) throws Exception {
101+
Options opt = new OptionsBuilder()
102+
.include("benchmark.CompletableFuturesBenchmark")
103+
.build();
104+
105+
new Runner(opt).run();
106+
}
107+
108+
}

0 commit comments

Comments
 (0)