197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes/*
297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * Copyright (C) 2011 Google Inc.
397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes *
497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * you may not use this file except in compliance with the License.
697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * You may obtain a copy of the License at
797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes *
897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0
997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes *
1097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * Unless required by applicable law or agreed to in writing, software
1197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
1297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * See the License for the specific language governing permissions and
1497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes * limitations under the License.
1597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes */
1697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
1797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughespackage benchmarks.regression;
1897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
1997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport java.util.Locale;
2097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport com.google.caliper.Param;
2197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughesimport com.google.caliper.SimpleBenchmark;
2297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
2397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughespublic class StringCaseMappingBenchmark extends SimpleBenchmark {
2497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    enum Inputs {
2597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        EMPTY(""),
2697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
2797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        // TODO: include hairy inputs like turkish and greek.
2897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        // TODO: locale makes a difference too.
2997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
3097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        LOWER2(lower(2)),
3197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        UPPER2(upper(2)),
3297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        MIXED2(mixed(2)),
3397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
3497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        LOWER8(lower(8)),
3597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        UPPER8(upper(8)),
3697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        MIXED8(mixed(8)),
3797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
3897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        LOWER32(lower(32)),
3997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        UPPER32(upper(32)),
4097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        MIXED32(mixed(32)),
4197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
4297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        LOWER512(lower(512)),
4397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        UPPER512(upper(512)),
4497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        MIXED512(mixed(512)),
4597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
4697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        LOWER2048(lower(2048)),
4797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        UPPER2048(upper(2048)),
4897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        MIXED2048(mixed(2048)),
4997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
5097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        LOWER_1M(lower(1024*1024)),
5197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        UPPER_1M(upper(1024*1024)),
5297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        MIXED_1M(mixed(1024*1024));
5397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
5497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        final String value;
5597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        private Inputs(String value) { this.value = value; }
5697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        private static String lower(int length) {
5797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            return makeString(length, "a0b1c2d3e4f5g6h7i8j9klmnopqrstuvwxyz");
5897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
5997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        private static String upper(int length) {
6097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            return makeString(length, "A0B1C2D3E4F5G6H7I8J9KLMNOPQRSTUVWXYZ");
6197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
6297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        private static String mixed(int length) {
6397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            return makeString(length, "Aa0Bb1Cc2Dd3Ee4Ff5Gg6Hh7Ii8Jj9KkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz");
6497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
6597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        private static String makeString(int length, String alphabet) {
6697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            StringBuilder sb = new StringBuilder(length);
6797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            for (int i = 0; i < length; ++i) {
6897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                sb.append(alphabet.charAt(i % alphabet.length()));
6997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            }
7097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            return sb.toString();
7197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
7297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    }
7397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    @Param private Inputs s;
7497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
7597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    public void timeToUpperCase_US(int reps) {
7697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        for (int i = 0; i < reps; ++i) {
7797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            s.value.toUpperCase(Locale.US);
7897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
7997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    }
8097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
81a2f8e8a253a93c8df8b0e6f458f4c573d48b9ed9Elliott Hughes    // toUpperCase for Greek is an extra-hard case that uses icu4c's Transliterator.
82a2f8e8a253a93c8df8b0e6f458f4c573d48b9ed9Elliott Hughes    public void timeToUpperCase_el_GR(int reps) {
83a2f8e8a253a93c8df8b0e6f458f4c573d48b9ed9Elliott Hughes        Locale el_GR = new Locale("el", "GR");
84a2f8e8a253a93c8df8b0e6f458f4c573d48b9ed9Elliott Hughes        for (int i = 0; i < reps; ++i) {
85a2f8e8a253a93c8df8b0e6f458f4c573d48b9ed9Elliott Hughes            s.value.toUpperCase(el_GR);
86a2f8e8a253a93c8df8b0e6f458f4c573d48b9ed9Elliott Hughes        }
87a2f8e8a253a93c8df8b0e6f458f4c573d48b9ed9Elliott Hughes    }
88a2f8e8a253a93c8df8b0e6f458f4c573d48b9ed9Elliott Hughes
8997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    public void timeToLowerCase_US(int reps) {
9097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        for (int i = 0; i < reps; ++i) {
9197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            s.value.toUpperCase(Locale.US);
9297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
9397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    }
9497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
9597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    public void timeToUpperCase_Ascii(int reps) {
9697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        for (int i = 0; i < reps; ++i) {
9797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            toUpperCaseAscii(s.value);
9897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
9997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    }
10097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
10197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    public void timeToLowerCase_Ascii(int reps) {
10297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        for (int i = 0; i < reps; ++i) {
10397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            toUpperCaseAscii(s.value);
10497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
10597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    }
10697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
10797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    public void timeToUpperCase_ICU(int reps) {
10897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        for (int i = 0; i < reps; ++i) {
109a94266074c7b82720fd2cecfb37ab8da85f1b296Elliott Hughes            libcore.icu.ICU.toUpperCase(s.value, Locale.US);
11097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
11197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    }
11297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
11397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    public void timeToLowerCase_ICU(int reps) {
11497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        for (int i = 0; i < reps; ++i) {
115a94266074c7b82720fd2cecfb37ab8da85f1b296Elliott Hughes            libcore.icu.ICU.toLowerCase(s.value, Locale.US);
11697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
11797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    }
11897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
11997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    public static String toUpperCaseAscii(String s) {
12097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        for (int i = 0, length = s.length(); i < length; i++) {
12197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            char c = s.charAt(i);
12297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            if (c < 'a' || c > 'z') {
12397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                continue; // fast path avoids allocation
12497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            }
12597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
12697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            // slow path: s contains lower case chars
12797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            char[] result = s.toCharArray();
12897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            for (; i < length; i++) {
12997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                c = result[i];
13097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                if (c >= 'a' && c <= 'z') {
13197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                    result[i] -= ('a' - 'A');
13297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                }
13397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            }
13497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            return new String(result);
13597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
13697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        return s;
13797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    }
13897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
13997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    public static String toLowerCaseAscii(String s) {
14097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        for (int i = 0, length = s.length(); i < length; i++) {
14197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            char c = s.charAt(i);
14297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            if (c < 'A' || c > 'Z') {
14397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                continue; // fast path avoids allocation
14497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            }
14597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes
14697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            // slow path: s contains upper case chars
14797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            char[] result = s.toCharArray();
14897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            for (; i < length; i++) {
14997aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                c = result[i];
15097aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                if (c >= 'A' && c <= 'Z') {
15197aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                    result[i] += ('a' - 'A');
15297aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes                }
15397aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            }
15497aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes            return new String(result);
15597aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        }
15697aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes        return s;
15797aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes    }
15897aba27f961a5a6f37dcaf7f455df371e250ede3Elliott Hughes}
159