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 java.util.BitSet; 23 import java.util.Random; 24 25 /** Benchmark for the {@link CharMatcher#whitespace} implementation. */ 26 public class WhitespaceMatcherBenchmark { 27 private static final int STRING_LENGTH = 10000; 28 29 private static final String OLD_WHITESPACE_TABLE = 30 "\u0001\u0000\u00a0\u0000\u0000\u0000\u0000\u0000" 31 + "\u0000\u0009\n\u000b\u000c\r\u0000\u0000\u2028\u2029\u0000\u0000\u0000\u0000\u0000" 32 + "\u202f\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0020\u0000\u0000\u0000\u0000" 33 + "\u0000\u0000\u0000\u0000\u0000\u0000\u3000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" 34 + "\u0000\u0000\u0000\u0085\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009" 35 + "\u200a\u0000\u0000\u0000\u0000\u0000\u205f\u1680\u0000\u0000\u180e\u0000\u0000\u0000"; 36 37 public static final CharMatcher OLD_WHITESPACE = 38 new CharMatcher() { 39 @Override 40 public boolean matches(char c) { 41 return OLD_WHITESPACE_TABLE.charAt(c % 79) == c; 42 } 43 }; 44 45 @Param private boolean useNew; 46 47 @Param({"20", "50", "80"}) 48 private int percentMatching; 49 50 private String teststring; 51 private CharMatcher matcher; 52 53 @BeforeExperiment setUp()54 protected void setUp() { 55 BitSet bitSet = new BitSet(); 56 for (int i = 0; i < OLD_WHITESPACE_TABLE.length(); i++) { 57 bitSet.set(OLD_WHITESPACE_TABLE.charAt(i)); 58 } 59 bitSet.clear(0); 60 bitSet.clear(1); 61 matcher = useNew ? CharMatcher.whitespace() : OLD_WHITESPACE; 62 teststring = newTestString(new Random(1), bitSet, percentMatching); 63 } 64 65 @Benchmark countIn(int reps)66 public int countIn(int reps) { 67 int result = 0; 68 CharMatcher matcher = this.matcher; 69 String teststring = this.teststring; 70 for (int i = 0; i < reps; i++) { 71 result += matcher.countIn(teststring); 72 } 73 return result; 74 } 75 76 @Benchmark collapseFrom(int reps)77 public int collapseFrom(int reps) { 78 int result = 0; 79 CharMatcher matcher = this.matcher; 80 String teststring = this.teststring; 81 for (int i = 0; i < reps; i++) { 82 result += System.identityHashCode(matcher.collapseFrom(teststring, ' ')); 83 } 84 return result; 85 } 86 allMatchingChars(BitSet bitSet)87 private static String allMatchingChars(BitSet bitSet) { 88 final char[] result = new char[bitSet.cardinality()]; 89 for (int j = 0, c = bitSet.nextSetBit(0); j < result.length; ++j) { 90 result[j] = (char) c; 91 c = bitSet.nextSetBit(c + 1); 92 } 93 return new String(result); 94 } 95 newTestString(Random random, BitSet bitSet, int percentMatching)96 private static String newTestString(Random random, BitSet bitSet, int percentMatching) { 97 final String allMatchingChars = allMatchingChars(bitSet); 98 final char[] result = new char[STRING_LENGTH]; 99 // Fill with matching chars. 100 for (int i = 0; i < result.length; i++) { 101 result[i] = allMatchingChars.charAt(random.nextInt(allMatchingChars.length())); 102 } 103 // Replace some of chars by non-matching. 104 int remaining = (int) ((100 - percentMatching) * result.length / 100.0 + 0.5); 105 while (remaining > 0) { 106 final char c = (char) random.nextInt(); 107 if (bitSet.get(c)) { 108 final int pos = random.nextInt(result.length); 109 if (bitSet.get(result[pos])) { 110 result[pos] = c; 111 remaining--; 112 } 113 } 114 } 115 return new String(result); 116 } 117 } 118