1/*
2 * Copyright (C) 2009 Google Inc.
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
17package examples;
18
19import com.google.caliper.BeforeExperiment;
20import com.google.caliper.Benchmark;
21import com.google.caliper.Param;
22
23/**
24 * Tests various Character methods, intended for testing multiple
25 * implementations against each other.
26 */
27public class CharacterBenchmark {
28
29    @Param private CharacterSet characterSet;
30
31    @Param private Overload overload;
32
33    private char[] chars;
34
35    @BeforeExperiment void setUp() throws Exception {
36        this.chars = characterSet.chars;
37    }
38
39    public enum Overload { CHAR, INT }
40
41    public enum CharacterSet {
42        ASCII(128),
43        UNICODE(65536);
44        final char[] chars;
45        CharacterSet(int size) {
46            this.chars = new char[65536];
47            for (int i = 0; i < 65536; ++i) {
48                chars[i] = (char) (i % size);
49            }
50        }
51    }
52
53    // A fake benchmark to give us a baseline.
54    @Benchmark boolean isSpace(int reps) {
55        boolean dummy = false;
56        if (overload == Overload.CHAR) {
57            for (int i = 0; i < reps; ++i) {
58                for (int ch = 0; ch < 65536; ++ch) {
59                    dummy ^= ((char) ch == ' ');
60                }
61            }
62        } else {
63            for (int i = 0; i < reps; ++i) {
64                for (int ch = 0; ch < 65536; ++ch) {
65                    dummy ^= (ch == ' ');
66                }
67            }
68        }
69        return dummy;
70    }
71
72    @Benchmark void digit(int reps) {
73        if (overload == Overload.CHAR) {
74            for (int i = 0; i < reps; ++i) {
75                for (int ch = 0; ch < 65536; ++ch) {
76                    Character.digit(chars[ch], 10);
77                }
78            }
79        } else {
80            for (int i = 0; i < reps; ++i) {
81                for (int ch = 0; ch < 65536; ++ch) {
82                    Character.digit((int) chars[ch], 10);
83                }
84            }
85        }
86    }
87
88    @Benchmark void getNumericValue(int reps) {
89        if (overload == Overload.CHAR) {
90            for (int i = 0; i < reps; ++i) {
91                for (int ch = 0; ch < 65536; ++ch) {
92                    Character.getNumericValue(chars[ch]);
93                }
94            }
95        } else {
96            for (int i = 0; i < reps; ++i) {
97                for (int ch = 0; ch < 65536; ++ch) {
98                    Character.getNumericValue((int) chars[ch]);
99                }
100            }
101        }
102    }
103
104    @Benchmark void isDigit(int reps) {
105        if (overload == Overload.CHAR) {
106            for (int i = 0; i < reps; ++i) {
107                for (int ch = 0; ch < 65536; ++ch) {
108                    Character.isDigit(chars[ch]);
109                }
110            }
111        } else {
112            for (int i = 0; i < reps; ++i) {
113                for (int ch = 0; ch < 65536; ++ch) {
114                    Character.isDigit((int) chars[ch]);
115                }
116            }
117        }
118    }
119
120    @Benchmark void isIdentifierIgnorable(int reps) {
121        if (overload == Overload.CHAR) {
122            for (int i = 0; i < reps; ++i) {
123                for (int ch = 0; ch < 65536; ++ch) {
124                    Character.isIdentifierIgnorable(chars[ch]);
125                }
126            }
127        } else {
128            for (int i = 0; i < reps; ++i) {
129                for (int ch = 0; ch < 65536; ++ch) {
130                    Character.isIdentifierIgnorable((int) chars[ch]);
131                }
132            }
133        }
134    }
135
136    @Benchmark void isJavaIdentifierPart(int reps) {
137        if (overload == Overload.CHAR) {
138            for (int i = 0; i < reps; ++i) {
139                for (int ch = 0; ch < 65536; ++ch) {
140                    Character.isJavaIdentifierPart(chars[ch]);
141                }
142            }
143        } else {
144            for (int i = 0; i < reps; ++i) {
145                for (int ch = 0; ch < 65536; ++ch) {
146                    Character.isJavaIdentifierPart((int) chars[ch]);
147                }
148            }
149        }
150    }
151
152    @Benchmark void isJavaIdentifierStart(int reps) {
153        if (overload == Overload.CHAR) {
154            for (int i = 0; i < reps; ++i) {
155                for (int ch = 0; ch < 65536; ++ch) {
156                    Character.isJavaIdentifierStart(chars[ch]);
157                }
158            }
159        } else {
160            for (int i = 0; i < reps; ++i) {
161                for (int ch = 0; ch < 65536; ++ch) {
162                    Character.isJavaIdentifierStart((int) chars[ch]);
163                }
164            }
165        }
166    }
167
168    @Benchmark void isLetter(int reps) {
169        if (overload == Overload.CHAR) {
170            for (int i = 0; i < reps; ++i) {
171                for (int ch = 0; ch < 65536; ++ch) {
172                    Character.isLetter(chars[ch]);
173                }
174            }
175        } else {
176            for (int i = 0; i < reps; ++i) {
177                for (int ch = 0; ch < 65536; ++ch) {
178                    Character.isLetter((int) chars[ch]);
179                }
180            }
181        }
182    }
183
184    @Benchmark void isLetterOrDigit(int reps) {
185        if (overload == Overload.CHAR) {
186            for (int i = 0; i < reps; ++i) {
187                for (int ch = 0; ch < 65536; ++ch) {
188                    Character.isLetterOrDigit(chars[ch]);
189                }
190            }
191        } else {
192            for (int i = 0; i < reps; ++i) {
193                for (int ch = 0; ch < 65536; ++ch) {
194                    Character.isLetterOrDigit((int) chars[ch]);
195                }
196            }
197        }
198    }
199
200    @Benchmark void isLowerCase(int reps) {
201        if (overload == Overload.CHAR) {
202            for (int i = 0; i < reps; ++i) {
203                for (int ch = 0; ch < 65536; ++ch) {
204                    Character.isLowerCase(chars[ch]);
205                }
206            }
207        } else {
208            for (int i = 0; i < reps; ++i) {
209                for (int ch = 0; ch < 65536; ++ch) {
210                    Character.isLowerCase((int) chars[ch]);
211                }
212            }
213        }
214    }
215
216    @Benchmark void isSpaceChar(int reps) {
217        if (overload == Overload.CHAR) {
218            for (int i = 0; i < reps; ++i) {
219                for (int ch = 0; ch < 65536; ++ch) {
220                    Character.isSpaceChar(chars[ch]);
221                }
222            }
223        } else {
224            for (int i = 0; i < reps; ++i) {
225                for (int ch = 0; ch < 65536; ++ch) {
226                    Character.isSpaceChar((int) chars[ch]);
227                }
228            }
229        }
230    }
231
232    @Benchmark void isUpperCase(int reps) {
233        if (overload == Overload.CHAR) {
234            for (int i = 0; i < reps; ++i) {
235                for (int ch = 0; ch < 65536; ++ch) {
236                    Character.isUpperCase(chars[ch]);
237                }
238            }
239        } else {
240            for (int i = 0; i < reps; ++i) {
241                for (int ch = 0; ch < 65536; ++ch) {
242                    Character.isUpperCase((int) chars[ch]);
243                }
244            }
245        }
246    }
247
248    @Benchmark void isWhitespace(int reps) {
249        if (overload == Overload.CHAR) {
250            for (int i = 0; i < reps; ++i) {
251                for (int ch = 0; ch < 65536; ++ch) {
252                    Character.isWhitespace(chars[ch]);
253                }
254            }
255        } else {
256            for (int i = 0; i < reps; ++i) {
257                for (int ch = 0; ch < 65536; ++ch) {
258                    Character.isWhitespace((int) chars[ch]);
259                }
260            }
261        }
262    }
263
264    @Benchmark void toLowerCase(int reps) {
265        if (overload == Overload.CHAR) {
266            for (int i = 0; i < reps; ++i) {
267                for (int ch = 0; ch < 65536; ++ch) {
268                    Character.toLowerCase(chars[ch]);
269                }
270            }
271        } else {
272            for (int i = 0; i < reps; ++i) {
273                for (int ch = 0; ch < 65536; ++ch) {
274                    Character.toLowerCase((int) chars[ch]);
275                }
276            }
277        }
278    }
279
280    @Benchmark void toUpperCase(int reps) {
281        if (overload == Overload.CHAR) {
282            for (int i = 0; i < reps; ++i) {
283                for (int ch = 0; ch < 65536; ++ch) {
284                    Character.toUpperCase(chars[ch]);
285                }
286            }
287        } else {
288            for (int i = 0; i < reps; ++i) {
289                for (int ch = 0; ch < 65536; ++ch) {
290                    Character.toUpperCase((int) chars[ch]);
291                }
292            }
293        }
294    }
295}
296