1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.util.concurrent;
17
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.TimeUnit;
20
21 import io.netty.channel.MultiThreadIoEventLoopGroup;
22 import io.netty.channel.nio.NioIoHandler;
23 import org.openjdk.jmh.annotations.Benchmark;
24 import org.openjdk.jmh.annotations.Level;
25 import org.openjdk.jmh.annotations.Measurement;
26 import org.openjdk.jmh.annotations.Param;
27 import org.openjdk.jmh.annotations.Scope;
28 import org.openjdk.jmh.annotations.Setup;
29 import org.openjdk.jmh.annotations.State;
30 import org.openjdk.jmh.annotations.TearDown;
31 import org.openjdk.jmh.annotations.Threads;
32 import org.openjdk.jmh.annotations.Warmup;
33
34 import io.netty.microbench.util.AbstractMicrobenchmark;
35
36 @Warmup(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS)
37 @Measurement(iterations = 10, time = 3, timeUnit = TimeUnit.SECONDS)
38 @State(Scope.Benchmark)
39 public class ScheduleFutureTaskBenchmark extends AbstractMicrobenchmark {
40
41 static final Callable<Void> NO_OP = new Callable<Void>() {
42 @Override
43 public Void call() throws Exception {
44 return null;
45 }
46 };
47
48 @State(Scope.Thread)
49 public static class ThreadState {
50
51 @Param({ "100000" })
52 int num;
53
54 AbstractScheduledEventExecutor eventLoop;
55
56 @Setup(Level.Trial)
57 public void reset() {
58 eventLoop = (AbstractScheduledEventExecutor) new MultiThreadIoEventLoopGroup(
59 1, NioIoHandler.newFactory()).next();
60 }
61
62 @Setup(Level.Invocation)
63 public void clear() {
64 eventLoop.submit(new Runnable() {
65 @Override
66 public void run() {
67 eventLoop.cancelScheduledTasks();
68 }
69 }).awaitUninterruptibly();
70 }
71
72 @TearDown(Level.Trial)
73 public void shutdown() {
74 clear();
75 eventLoop.parent().shutdownGracefully().awaitUninterruptibly();
76 }
77 }
78
79 @Benchmark
80 @Threads(3)
81 public Future<?> scheduleLots(final ThreadState threadState) {
82 return threadState.eventLoop.submit(new Runnable() {
83 @Override
84 public void run() {
85 for (int i = 1; i <= threadState.num; i++) {
86 threadState.eventLoop.schedule(NO_OP, i, TimeUnit.HOURS);
87 }
88 }
89 }).syncUninterruptibly();
90 }
91
92 @Benchmark
93 @Threads(1)
94 public Future<?> scheduleLotsOutsideLoop(final ThreadState threadState) {
95 final AbstractScheduledEventExecutor eventLoop = threadState.eventLoop;
96 for (int i = 1; i <= threadState.num; i++) {
97 eventLoop.schedule(NO_OP, i, TimeUnit.HOURS);
98 }
99 return null;
100 }
101
102 @Benchmark
103 @Threads(1)
104 public Future<?> scheduleCancelLotsOutsideLoop(final ThreadState threadState) {
105 final AbstractScheduledEventExecutor eventLoop = threadState.eventLoop;
106 for (int i = 1; i <= threadState.num; i++) {
107 eventLoop.schedule(NO_OP, i, TimeUnit.HOURS).cancel(false);
108 }
109 return null;
110 }
111 }