• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.base;
18 
19 import com.google.caliper.BeforeExperiment;
20 import com.google.caliper.Benchmark;
21 import com.google.caliper.Param;
22 import com.google.common.collect.Lists;
23 import com.google.common.primitives.Chars;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Locale;
27 import java.util.Random;
28 
29 /**
30  * Benchmarks for the ASCII class.
31  *
32  * @author Kevin Bourrillion
33  */
34 public class AsciiBenchmark {
35   private static final String ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
36   private static final String NONALPHA = "0123456789`~-_=+[]{}|;:',.<>/?!@#$%^&*()\"\\";
37 
38   @Param({"20", "2000"})
39   int size;
40 
41   @Param({"2", "20"})
42   int nonAlphaRatio; // one non-alpha char per this many chars
43 
44   @Param boolean noWorkToDo;
45 
46   Random random;
47   String testString;
48 
49   @BeforeExperiment
setUp()50   void setUp() {
51     random = new Random(0xdeadbeef); // fix the seed so results are comparable across runs
52 
53     int nonAlpha = size / nonAlphaRatio;
54     int alpha = size - nonAlpha;
55 
56     List<Character> chars = Lists.newArrayListWithCapacity(size);
57     for (int i = 0; i < alpha; i++) {
58       chars.add(randomAlpha());
59     }
60     for (int i = 0; i < nonAlpha; i++) {
61       chars.add(randomNonAlpha());
62     }
63     Collections.shuffle(chars, random);
64     char[] array = Chars.toArray(chars);
65     this.testString = new String(array);
66   }
67 
randomAlpha()68   private char randomAlpha() {
69     return ALPHA.charAt(random.nextInt(ALPHA.length()));
70   }
71 
randomNonAlpha()72   private char randomNonAlpha() {
73     return NONALPHA.charAt(random.nextInt(NONALPHA.length()));
74   }
75 
76   @Benchmark
asciiStringToUpperCase(int reps)77   int asciiStringToUpperCase(int reps) {
78     String string = noWorkToDo ? Ascii.toUpperCase(testString) : testString;
79 
80     int dummy = 0;
81     for (int i = 0; i < reps; i++) {
82       dummy += Ascii.toUpperCase(string).length();
83     }
84     return dummy;
85   }
86 
87   @Benchmark
asciiCharSequenceToUpperCase(int reps)88   int asciiCharSequenceToUpperCase(int reps) {
89     String string = noWorkToDo ? charSequenceToUpperCase(testString) : testString;
90 
91     int dummy = 0;
92     for (int i = 0; i < reps; i++) {
93       dummy += charSequenceToUpperCase(string).length();
94     }
95     return dummy;
96   }
97 
98   @Benchmark
stringToUpperCase(int reps)99   int stringToUpperCase(int reps) {
100     String string = noWorkToDo ? testString.toUpperCase(Locale.US) : testString;
101 
102     int dummy = 0;
103     for (int i = 0; i < reps; i++) {
104       dummy += string.toUpperCase(Locale.US).length();
105     }
106     return dummy;
107   }
108 
109   @Benchmark
equalsIgnoreCaseCharSequence(int reps)110   boolean equalsIgnoreCaseCharSequence(int reps) {
111     // This benchmark has no concept of "noWorkToDo".
112     String upperString = testString.toUpperCase();
113     CharSequence testSeq = new StringBuilder(testString);
114     CharSequence upperSeq = new StringBuilder(upperString);
115     CharSequence[] lhs = new CharSequence[] {testString, testSeq, testString, testSeq};
116     CharSequence[] rhs = new CharSequence[] {upperString, upperString, upperSeq, upperSeq};
117 
118     boolean dummy = false;
119     for (int i = 0; i < reps; i++) {
120       dummy ^= Ascii.equalsIgnoreCase(lhs[i & 0x3], rhs[i & 0x3]);
121     }
122     return dummy;
123   }
124 
125   @Benchmark
equalsIgnoreCaseStringOnly(int reps)126   boolean equalsIgnoreCaseStringOnly(int reps) {
127     // This benchmark has no concept of "noWorkToDo".
128     String lhs = testString;
129     String rhs = testString.toUpperCase();
130 
131     boolean dummy = false;
132     for (int i = 0; i < reps; i++) {
133       dummy ^= Ascii.equalsIgnoreCase(lhs, rhs);
134     }
135     return dummy;
136   }
137 
138   @Benchmark
equalsIgnoreCaseJDK(int reps)139   boolean equalsIgnoreCaseJDK(int reps) {
140     // This benchmark has no concept of "noWorkToDo".
141     String lhs = testString;
142     String rhs = testString.toUpperCase();
143 
144     boolean dummy = false;
145     for (int i = 0; i < reps; i++) {
146       dummy ^= lhs.equalsIgnoreCase(rhs);
147     }
148     return dummy;
149   }
150 
151   @Benchmark
isUpperCase(int reps)152   boolean isUpperCase(int reps) {
153     // This benchmark has no concept of "noWorkToDo".
154     char[] chars = testString.toCharArray();
155 
156     boolean dummy = false;
157     for (int i = 0; i < reps; i++) {
158       for (int n = 0; n < chars.length; n++) {
159         dummy ^= Ascii.isUpperCase(chars[n]);
160       }
161     }
162     return dummy;
163   }
164 
charSequenceToUpperCase(CharSequence chars)165   static String charSequenceToUpperCase(CharSequence chars) {
166     char[] newChars = new char[chars.length()];
167     for (int i = 0; i < newChars.length; i++) {
168       newChars[i] = Ascii.toUpperCase(chars.charAt(i));
169     }
170     return String.valueOf(newChars);
171   }
172 }
173