View Javadoc
1   /*
2    * Copyright 2019 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
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 }