View Javadoc
1   /*
2    * Copyright 2020 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.handler.codec.mqtt;
17  
18  import io.netty.microbench.util.AbstractMicrobenchmark;
19  import org.openjdk.jmh.annotations.Benchmark;
20  import org.openjdk.jmh.annotations.BenchmarkMode;
21  import org.openjdk.jmh.annotations.Measurement;
22  import org.openjdk.jmh.annotations.Mode;
23  import org.openjdk.jmh.annotations.OutputTimeUnit;
24  import org.openjdk.jmh.annotations.Setup;
25  import org.openjdk.jmh.annotations.Warmup;
26  
27  import java.util.concurrent.TimeUnit;
28  
29  @BenchmarkMode(Mode.AverageTime)
30  @Warmup(iterations = 5, time = 5)
31  @Measurement(iterations = 5, time = 5)
32  @OutputTimeUnit(TimeUnit.NANOSECONDS)
33  public class MqttMessageTypeValueOfBench extends AbstractMicrobenchmark {
34  
35      private static final int[] DATASET = new int[] {
36              9, 5, 2, 9, 8, 4, 3, 7, 7, 9, 6, 11, 10, 4, 10, 6, 12, 6, 14, 8, 2, 2, 5, 7, 13, 3, 10, 12, 6, 2, 8, 1, 6,
37              4, 10, 8, 13, 9, 9, 2, 7, 12, 2, 3, 12, 9, 3, 12,
38              11, 4, 10, 11, 9, 10, 5, 9, 4, 14, 6, 10, 13, 9, 12, 7, 5, 3, 1, 2, 7, 11, 1, 8, 4, 9, 5, 11, 14, 6, 3, 4,
39              3, 1, 12, 9, 6, 1, 10, 2, 9, 5, 10, 4, 5, 1, 8,
40              2, 11, 9, 7, 10, 14, 9, 12, 14, 6, 13, 6, 14, 6, 1, 3, 1, 10, 13, 13, 2, 2, 8, 7, 10, 9, 9, 4, 7, 13, 4, 10,
41              3, 14, 14, 4, 3, 6, 7, 13, 13, 2, 3, 13, 5, 2,
42              14, 11, 1, 5, 6, 14, 13, 12, 3, 9, 10, 1, 4, 1, 1, 13, 5, 8, 1, 8, 2, 7, 9, 14, 13, 2, 11, 10, 11, 5, 9, 13,
43              13, 12, 11, 6, 1, 7, 11, 1, 11, 7, 8, 1, 13,
44              12, 1, 5, 10, 2, 13, 4, 8, 2, 14, 8, 8, 9, 14, 12, 11, 1, 10, 6, 7, 2, 1, 12, 11, 8, 9, 10, 13, 2, 12, 3, 8,
45              1, 13, 11, 8, 6, 4, 5, 8, 5, 12, 10, 9, 4, 7,
46              2, 1, 11, 6, 7, 11, 5, 1, 5, 2, 7, 7, 14, 14, 3, 2, 1, 8, 5, 7, 4, 13, 13, 7, 8, 2, 14, 1, 12, 7, 8, 8, 3,
47              9, 8, 1, 11, 10, 13, 10, 2, 1, 12, 5, 3, 3, 12, 5,
48              7, 12, 13, 10, 14, 9, 2, 4, 12, 4, 10, 10, 2, 9, 2, 7, 5, 6, 2, 14, 10, 3, 4, 5, 8, 1, 14, 13, 1, 2, 5, 11,
49              8, 6, 8, 3, 8, 13, 12, 8, 2, 12, 6, 2, 5, 4, 13,
50              5, 11, 11, 5, 12, 9, 9, 9, 6, 4, 4, 11, 14, 12, 9, 3, 4, 12, 10, 10, 6, 3, 2, 12, 3, 2, 10, 8, 7, 10, 12,
51              13, 1, 2, 7, 13, 2, 13, 4, 13, 14, 10, 14, 7, 5,
52              11, 10, 9, 9, 1, 9, 10, 3, 9, 1, 13, 7, 9, 7, 1, 8, 14, 2, 6, 11, 2, 2, 11, 4, 10, 10, 9, 4, 4, 13, 7, 2, 1,
53              4, 14, 6, 11, 5, 2, 5, 9, 5, 8, 4, 5, 6, 2, 12, 2,
54              5, 2, 14, 3, 11, 5, 4, 14, 14, 2, 7, 7, 2, 3, 11, 2, 10, 9, 13, 3, 4, 2, 10, 1, 2, 10, 7, 7, 6, 8, 8, 12,
55              14, 8, 13, 1, 9, 5, 9, 1, 14, 2, 5, 5, 5, 3, 13, 11,
56              9, 6, 11, 1, 10, 13, 4, 7, 9, 6, 3, 4, 11, 8, 13, 3, 13, 12, 7, 7, 5, 9, 11, 3, 9, 6, 5, 6, 6, 11, 9, 2, 7,
57              1, 12, 7, 5, 8, 11, 4, 9, 10, 11, 12, 7, 8, 1, 2,
58              3, 14, 3, 9, 11, 9, 7, 4, 4, 4, 8, 4, 4, 2, 5, 8, 2, 11, 7, 13, 2, 14, 3, 6, 7, 14, 12, 6, 9, 11, 10, 9, 6,
59              10, 6, 14, 4, 1, 7, 12, 4, 13, 10, 2, 2, 3, 3, 14,
60              14, 2, 9, 12, 3, 9, 7, 6, 12, 8, 9, 5, 11, 13, 14, 14, 4, 1, 11, 14, 5, 9, 7, 14, 7, 13, 7, 14, 3, 14, 2, 8,
61              2, 5, 10, 12, 14, 9, 11, 3, 14, 8, 12, 12, 5, 2,
62              6, 2, 1, 14, 12, 8, 14, 1, 11, 14, 8, 9, 9, 1, 12, 13, 7, 8, 10, 5, 8, 5, 14, 13, 14, 3, 14, 2, 9, 12, 3,
63              10, 3, 2, 4, 3, 5, 5, 10, 10, 13, 10, 7, 6, 4, 2, 10,
64              8, 14, 2, 7, 1, 2, 7, 13, 2, 3, 6, 14, 3, 8, 12, 3, 4, 12, 6, 3, 10, 6, 14, 9, 1, 6, 3, 14, 7, 1, 7, 2, 12,
65              9, 5, 9, 6, 13, 5, 11, 13, 11, 10, 1, 14, 9, 13, 8,
66              12, 14, 14, 8, 13, 2, 6, 14, 2, 2, 9, 12, 9, 7, 2, 11, 4, 6, 8, 10, 12, 10, 11, 2, 9, 9, 5, 4, 3, 4, 4, 10,
67              3, 1, 12, 13, 9, 8, 1, 9, 9, 4, 2, 7, 3, 4, 11, 11,
68              8, 10, 14, 5, 14, 1, 10, 10, 13, 5, 6, 13, 14, 5, 7, 11, 4, 13, 3, 14, 7, 2, 10, 13, 2, 4, 14, 5, 1, 12, 3,
69              13, 11, 2, 11, 14, 2, 5, 8, 13, 4, 13, 13, 3, 3,
70              3, 13, 6, 11, 5, 3, 2, 13, 9, 2, 10, 8, 3, 11, 4, 6, 12, 14, 6, 2, 14, 1, 2, 6, 8, 4, 12, 8, 11, 9, 1, 7, 1,
71              10, 4, 10, 9, 9, 3, 11, 5, 10, 8, 9, 4, 13, 4,
72              5, 7, 12, 14, 12, 6, 1, 2, 10, 9, 10, 12, 1, 2, 6, 9, 5, 13, 4, 6, 11, 7, 1, 3, 10, 2, 1, 13, 14, 3, 5, 5,
73              5, 7, 14, 9, 9, 3, 12, 1, 1, 1, 3, 12, 6, 9, 7, 8, 1,
74              8, 2, 8, 13, 1, 11, 11, 1, 4, 10, 4, 3, 10, 3, 2, 2, 8, 2, 4, 13, 14, 4, 12, 14, 7, 6, 7, 13, 7, 11, 13, 12,
75              14, 1, 14, 3, 4, 13, 12, 10, 5, 12, 12, 4, 5, 6,
76              9, 12, 13, 3, 4, 13, 8, 14, 3, 2, 8, 5, 6, 13, 8, 7, 4, 5, 8, 14, 8, 14, 7, 5, 4, 9, 12, 12, 10, 3, 1, 12,
77              5, 1, 11, 6, 10, 5, 14, 4, 5, 13, 8, 11, 13, 4, 9,
78              9, 7, 6, 2, 2, 5, 12, 13, 13, 6, 11, 13, 12, 10, 6, 7, 1, 2, 6, 1, 9, 10, 14, 7, 9, 2, 2, 2, 8, 8, 11, 14,
79              12, 9, 13, 1
80      };
81  
82      int[] types;
83      long next;
84      long mask;
85  
86      @Setup
87      public void initDataSet() {
88          types = DATASET;
89          next = 0;
90          mask = types.length - 1;
91          if (Integer.bitCount(types.length) != 1) {
92              throw new AssertionError("The data set should contains power of 2 items");
93          }
94      }
95  
96      @Benchmark
97      public MqttMessageType getViaArray() {
98          long next = this.next;
99          int nextIndex = (int) (next & mask);
100         MqttMessageType type = MqttMessageType.valueOf(types[nextIndex]);
101         this.next = next + 1;
102         return type;
103     }
104 
105     @Benchmark
106     public MqttMessageType getViaSwitch() {
107         long next = this.next;
108         int nextIndex = (int) (next & mask);
109         MqttMessageType type = switchValueOf(types[nextIndex]);
110         this.next = next + 1;
111         return type;
112     }
113 
114     private static MqttMessageType switchValueOf(int type) {
115         switch (type) {
116         case 1:
117             return MqttMessageType.CONNECT;
118         case 2:
119             return MqttMessageType.CONNACK;
120         case 3:
121             return MqttMessageType.PUBLISH;
122         case 4:
123             return MqttMessageType.PUBACK;
124         case 5:
125             return MqttMessageType.PUBREC;
126         case 6:
127             return MqttMessageType.PUBREL;
128         case 7:
129             return MqttMessageType.PUBCOMP;
130         case 8:
131             return MqttMessageType.SUBSCRIBE;
132         case 9:
133             return MqttMessageType.SUBACK;
134         case 10:
135             return MqttMessageType.UNSUBSCRIBE;
136         case 11:
137             return MqttMessageType.UNSUBACK;
138         case 12:
139             return MqttMessageType.PINGREQ;
140         case 13:
141             return MqttMessageType.PINGRESP;
142         case 14:
143             return MqttMessageType.DISCONNECT;
144         default:
145             throw new IllegalArgumentException("unknown message type: " + type);
146         }
147     }
148 }