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.base.Ascii; 23 import com.google.common.collect.Lists; 24 import com.google.common.primitives.Chars; 25 26 import java.util.Collections; 27 import java.util.List; 28 import java.util.Locale; 29 import java.util.Random; 30 31 /** 32 * Benchmarks for the ASCII class. 33 * 34 * @author Kevin Bourrillion 35 */ 36 public class AsciiBenchmark { 37 private static String ALPHA = 38 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 39 private static String NONALPHA = 40 "0123456789`~-_=+[]{}|;:',.<>/?!@#$%^&*()\"\\"; 41 42 @Param({"20", "2000"}) int size; 43 @Param({"2", "20"}) int nonAlphaRatio; // one non-alpha char per this many chars 44 @Param boolean noWorkToDo; 45 46 Random random; 47 String testString; 48 49 @BeforeExperiment void setUp() { 50 random = new Random(); 51 52 int nonAlpha = size / nonAlphaRatio; 53 int alpha = size - nonAlpha; 54 55 List<Character> chars = Lists.newArrayListWithCapacity(size); 56 for (int i = 0; i < alpha; i++) { 57 chars.add(randomAlpha()); 58 } 59 for (int i = 0; i < nonAlpha; i++) { 60 chars.add(randomNonAlpha()); 61 } 62 Collections.shuffle(chars, random); 63 char[] array = Chars.toArray(chars); 64 this.testString = new String(array); 65 } 66 67 private char randomAlpha() { 68 return ALPHA.charAt(random.nextInt(ALPHA.length())); 69 } 70 71 private char randomNonAlpha() { 72 return NONALPHA.charAt(random.nextInt(NONALPHA.length())); 73 } 74 75 @Benchmark int asciiStringToUpperCase(int reps) { 76 String string = noWorkToDo 77 ? Ascii.toUpperCase(testString) 78 : 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 int asciiCharSequenceToUpperCase(int reps) { 88 String string = noWorkToDo 89 ? charSequenceToUpperCase(testString) 90 : testString; 91 92 int dummy = 0; 93 for (int i = 0; i < reps; i++) { 94 dummy += charSequenceToUpperCase(string).length(); 95 } 96 return dummy; 97 } 98 99 @Benchmark int stringToUpperCase(int reps) { 100 String string = noWorkToDo 101 ? testString.toUpperCase(Locale.US) 102 : testString; 103 104 int dummy = 0; 105 for (int i = 0; i < reps; i++) { 106 dummy += string.toUpperCase(Locale.US).length(); 107 } 108 return dummy; 109 } 110 111 @Benchmark boolean equalsIgnoreCaseCharSequence(int reps) { 112 // This benchmark has no concept of "noWorkToDo". 113 String upperString = testString.toUpperCase(); 114 CharSequence testSeq = new StringBuilder(testString); 115 CharSequence upperSeq = new StringBuilder(upperString); 116 CharSequence[] lhs = new CharSequence[] { testString, testSeq, testString, testSeq }; 117 CharSequence[] rhs = new CharSequence[] { upperString, upperString, upperSeq, upperSeq }; 118 119 boolean dummy = false; 120 for (int i = 0; i < reps; i++) { 121 dummy ^= Ascii.equalsIgnoreCase(lhs[i & 0x3], rhs[i & 0x3]); 122 } 123 return dummy; 124 } 125 126 @Benchmark 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 boolean equalsIgnoreCaseJDK(int reps) { 139 // This benchmark has no concept of "noWorkToDo". 140 String lhs = testString; 141 String rhs = testString.toUpperCase(); 142 143 boolean dummy = false; 144 for (int i = 0; i < reps; i++) { 145 dummy ^= lhs.equalsIgnoreCase(rhs); 146 } 147 return dummy; 148 } 149 150 @Benchmark boolean isUpperCase(int reps) { 151 // This benchmark has no concept of "noWorkToDo". 152 char[] chars = testString.toCharArray(); 153 154 boolean dummy = false; 155 for (int i = 0; i < reps; i++) { 156 for (int n = 0; n < chars.length; n++) { 157 dummy ^= Ascii.isUpperCase(chars[n]); 158 } 159 } 160 return dummy; 161 } 162 163 static String charSequenceToUpperCase(CharSequence chars) { 164 int length = chars.length(); 165 StringBuilder builder = new StringBuilder(length); 166 for (int i = 0; i < length; i++) { 167 builder.append(Ascii.toUpperCase(chars.charAt(i))); 168 } 169 return builder.toString(); 170 } 171 } 172