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