View Javadoc
1   /*
2    * Copyright 2024 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;
17  
18  import io.netty.util.internal.SuppressJava6Requirement;
19  import org.openjdk.jmh.annotations.Benchmark;
20  import org.openjdk.jmh.annotations.Fork;
21  import org.openjdk.jmh.annotations.Level;
22  import org.openjdk.jmh.annotations.Measurement;
23  import org.openjdk.jmh.annotations.OutputTimeUnit;
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.Threads;
29  import org.openjdk.jmh.annotations.Warmup;
30  
31  import java.util.SplittableRandom;
32  import java.util.concurrent.TimeUnit;
33  
34  @Threads(1)
35  @OutputTimeUnit(TimeUnit.MICROSECONDS)
36  @Fork(2)
37  @Warmup(iterations = 5, time = 1)
38  @Measurement(iterations = 8, time = 1)
39  @State(Scope.Benchmark)
40  public class AsciiStringCaseConversionBenchmark {
41      @Param({ "7", "16", "23", "32" })
42      int size;
43  
44      @Param({ "4", "11" })
45      int logPermutations;
46  
47      @Param({ "0" })
48      int seed;
49  
50      int permutations;
51  
52      AsciiString[] asciiStringData;
53  
54      String[] stringData;
55  
56      byte[] ret;
57  
58      private int i;
59  
60      @Param({ "true", "false" })
61      private boolean noUnsafe;
62  
63      @Setup(Level.Trial)
64      @SuppressJava6Requirement(reason = "using SplittableRandom to reliably produce data")
65      public void init() {
66          System.setProperty("io.netty.noUnsafe", Boolean.valueOf(noUnsafe).toString());
67          final SplittableRandom random = new SplittableRandom(seed);
68          permutations = 1 << logPermutations;
69          ret = new byte[size];
70          asciiStringData = new AsciiString[permutations];
71          stringData = new String[permutations];
72          for (int i = 0; i < permutations; ++i) {
73              final int foundIndex = random.nextInt(Math.max(0, size - 8), size);
74              final byte[] byteArray = new byte[size];
75              int j = 0;
76              for (; j < size; j++) {
77                  byte value = (byte) random.nextInt(0, (int) Byte.MAX_VALUE + 1);
78                  // turn any found value into something different
79                  if (j < foundIndex) {
80                      if (AsciiStringUtil.isUpperCase(value)) {
81                          value = AsciiStringUtil.toLowerCase(value);
82                      }
83                  }
84                  if (j == foundIndex) {
85                      value = 'N';
86                  }
87                  byteArray[j] = value;
88              }
89              asciiStringData[i] = new AsciiString(byteArray, false);
90              stringData[i] = asciiStringData[i].toString();
91          }
92      }
93  
94      private AsciiString getData() {
95          return asciiStringData[i++ & permutations - 1];
96      }
97  
98      private String getStringData() {
99          return stringData[i++ & permutations - 1];
100     }
101 
102     @Benchmark
103     public AsciiString toLowerCase() {
104         return getData().toLowerCase();
105     }
106 
107     @Benchmark
108     public AsciiString toUpperCase() {
109         return getData().toUpperCase();
110     }
111 
112     @Benchmark
113     public String stringToLowerCase() {
114         return getStringData().toLowerCase();
115     }
116 
117     @Benchmark
118     public String stringtoUpperCase() {
119         return getStringData().toUpperCase();
120     }
121 
122 }