StringCaseMappingBenchmark.java revision 5a7833b406bb2716b057d3ed923f22f1f86b2a20
1/*
2 * Copyright (C) 2011 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 benchmarks.regression;
18
19import java.util.Locale;
20import com.google.caliper.Param;
21import com.google.caliper.SimpleBenchmark;
22
23public class StringCaseMappingBenchmark extends SimpleBenchmark {
24    enum Inputs {
25        EMPTY(""),
26
27        // TODO: include hairy inputs like turkish and greek.
28        // TODO: locale makes a difference too.
29
30        LOWER2(lower(2)),
31        UPPER2(upper(2)),
32        MIXED2(mixed(2)),
33
34        LOWER8(lower(8)),
35        UPPER8(upper(8)),
36        MIXED8(mixed(8)),
37
38        LOWER32(lower(32)),
39        UPPER32(upper(32)),
40        MIXED32(mixed(32)),
41
42        LOWER512(lower(512)),
43        UPPER512(upper(512)),
44        MIXED512(mixed(512)),
45
46        LOWER2048(lower(2048)),
47        UPPER2048(upper(2048)),
48        MIXED2048(mixed(2048)),
49
50        LOWER_1M(lower(1024*1024)),
51        UPPER_1M(upper(1024*1024)),
52        MIXED_1M(mixed(1024*1024));
53
54        final String value;
55        private Inputs(String value) { this.value = value; }
56        private static String lower(int length) {
57            return makeString(length, "a0b1c2d3e4f5g6h7i8j9klmnopqrstuvwxyz");
58        }
59        private static String upper(int length) {
60            return makeString(length, "A0B1C2D3E4F5G6H7I8J9KLMNOPQRSTUVWXYZ");
61        }
62        private static String mixed(int length) {
63            return makeString(length, "Aa0Bb1Cc2Dd3Ee4Ff5Gg6Hh7Ii8Jj9KkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz");
64        }
65        private static String makeString(int length, String alphabet) {
66            StringBuilder sb = new StringBuilder(length);
67            for (int i = 0; i < length; ++i) {
68                sb.append(alphabet.charAt(i % alphabet.length()));
69            }
70            return sb.toString();
71        }
72    }
73    @Param private Inputs s;
74
75    public void timeToUpperCase_US(int reps) {
76        for (int i = 0; i < reps; ++i) {
77            s.value.toUpperCase(Locale.US);
78        }
79    }
80
81    public void timeToLowerCase_US(int reps) {
82        for (int i = 0; i < reps; ++i) {
83            s.value.toUpperCase(Locale.US);
84        }
85    }
86
87    public void timeToUpperCase_Ascii(int reps) {
88        for (int i = 0; i < reps; ++i) {
89            toUpperCaseAscii(s.value);
90        }
91    }
92
93    public void timeToLowerCase_Ascii(int reps) {
94        for (int i = 0; i < reps; ++i) {
95            toUpperCaseAscii(s.value);
96        }
97    }
98
99    public void timeToUpperCase_ICU(int reps) {
100        for (int i = 0; i < reps; ++i) {
101            libcore.icu.ICU.toUpperCase(s.value, Locale.US.toString());
102        }
103    }
104
105    public void timeToLowerCase_ICU(int reps) {
106        for (int i = 0; i < reps; ++i) {
107            libcore.icu.ICU.toLowerCase(s.value, Locale.US.toString());
108        }
109    }
110
111    public static String toUpperCaseAscii(String s) {
112        for (int i = 0, length = s.length(); i < length; i++) {
113            char c = s.charAt(i);
114            if (c < 'a' || c > 'z') {
115                continue; // fast path avoids allocation
116            }
117
118            // slow path: s contains lower case chars
119            char[] result = s.toCharArray();
120            for (; i < length; i++) {
121                c = result[i];
122                if (c >= 'a' && c <= 'z') {
123                    result[i] -= ('a' - 'A');
124                }
125            }
126            return new String(result);
127        }
128        return s;
129    }
130
131    public static String toLowerCaseAscii(String s) {
132        for (int i = 0, length = s.length(); i < length; i++) {
133            char c = s.charAt(i);
134            if (c < 'A' || c > 'Z') {
135                continue; // fast path avoids allocation
136            }
137
138            // slow path: s contains upper case chars
139            char[] result = s.toCharArray();
140            for (; i < length; i++) {
141                c = result[i];
142                if (c >= 'A' && c <= 'Z') {
143                    result[i] += ('a' - 'A');
144                }
145            }
146            return new String(result);
147        }
148        return s;
149    }
150}
151