1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.util.concurrent;
18
19 import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
20 import static com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService;
21
22 import com.google.caliper.AfterExperiment;
23 import com.google.caliper.BeforeExperiment;
24 import com.google.caliper.Benchmark;
25 import com.google.caliper.Param;
26 import com.google.caliper.api.Footprint;
27 import com.google.caliper.api.VmOptions;
28
29 import java.util.HashSet;
30 import java.util.Set;
31 import java.util.concurrent.Executor;
32 import java.util.concurrent.atomic.AtomicInteger;
33
34
35
36
37
38 @VmOptions({"-Xms12g", "-Xmx12g", "-d64"})
39 public class MoreExecutorsDirectExecutorBenchmark {
40 enum Impl {
41 EXECUTOR_SERVICE {
42 @Override Executor executor() {
43 return newDirectExecutorService();
44 }
45 },
46 EXECUTOR {
47 @Override Executor executor() {
48 return directExecutor();
49 }
50 };
51 abstract Executor executor();
52 }
53
54 @Param Impl impl;
55 Executor executor;
56
57 static final class CountingRunnable implements Runnable {
58 AtomicInteger integer = new AtomicInteger();
59 @Override public void run() {
60 integer.incrementAndGet();
61 }
62 }
63
64 CountingRunnable countingRunnable = new CountingRunnable();
65
66 Set<Thread> threads = new HashSet<Thread>();
67
68 @BeforeExperiment void before() {
69 executor = impl.executor();
70 for (int i = 0; i < 4; i++) {
71 Thread thread = new Thread() {
72 @Override public void run() {
73 CountingRunnable localRunnable = new CountingRunnable();
74 while (!isInterrupted()) {
75 executor.execute(localRunnable);
76 }
77 countingRunnable.integer.addAndGet(localRunnable.integer.get());
78 }
79 };
80 threads.add(thread);
81 }
82 }
83
84 @AfterExperiment void after() {
85 for (Thread thread : threads) {
86 thread.interrupt();
87 }
88 threads.clear();
89 }
90
91 @Footprint Object measureSize() {
92 return executor;
93 }
94
95 @Benchmark int timeUncontendedExecute(int reps) {
96 final Executor executor = this.executor;
97 final CountingRunnable countingRunnable = this.countingRunnable;
98 for (int i = 0; i < reps; i++) {
99 executor.execute(countingRunnable);
100 }
101 return countingRunnable.integer.get();
102 }
103
104 @Benchmark int timeContendedExecute(int reps) {
105 final Executor executor = this.executor;
106 for (Thread thread : threads) {
107 if (!thread.isAlive()) {
108 thread.start();
109 }
110 }
111 final CountingRunnable countingRunnable = this.countingRunnable;
112 for (int i = 0; i < reps; i++) {
113 executor.execute(countingRunnable);
114 }
115 return countingRunnable.integer.get();
116 }
117 }