1545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir/*
2545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir * Copyright (C) 2016 The Android Open Source Project
3545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir *
4545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir * Licensed under the Apache License, Version 2.0 (the "License");
5545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir * you may not use this file except in compliance with the License.
6545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir * You may obtain a copy of the License at
7545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir *
8545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir *      http://www.apache.org/licenses/LICENSE-2.0
9545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir *
10545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir * Unless required by applicable law or agreed to in writing, software
11545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir * distributed under the License is distributed on an "AS IS" BASIS,
12545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir * See the License for the specific language governing permissions and
14545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir * limitations under the License.
15545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir */
16545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
17545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirpackage android.text.util;
18545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
19545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirimport com.google.caliper.AfterExperiment;
20545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirimport com.google.caliper.BeforeExperiment;
21545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirimport com.google.caliper.Benchmark;
22545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirimport com.google.caliper.Param;
23545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
24545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirimport android.text.Spannable;
25545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirimport android.text.SpannableString;
26545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirimport android.util.Patterns;
27545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
28545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirimport java.util.regex.Pattern;
29545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
30545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinirpublic class LinkifyBenchmark {
31545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    private static final String MATCHING_STR = " http://user:pass@host.com:5432/path?k=v#f " +
32545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir            "host.com:5432/path?k=v#f ";
33545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
34545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    private static final String NONMATCHING_STR = " Neque porro quisquam est qui dolorem ipsum " +
35545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir            "quia dolor sit amet, consectetur, adipisci velit ";
36545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
37545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    // this pattern does not recognize strings without http scheme therefore is expected to be
38545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    // faster in MATCHING_STR case.
39545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    private static final Pattern BASIC_PATTERN = Pattern.compile(
40545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir            "(?:\\b|$|^)http://[a-zA-Z0-9:\\.@\\?=#/]+(?:\\b|$|^)");
41545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
42545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    @Param({"1", "4", "16", "64", "256"})
43545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    private String mParamCopyAmount;
44545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
45545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    @Param({MATCHING_STR, NONMATCHING_STR})
46545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    private String mParamBasicText;
47545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
48545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    private Spannable mTestSpannable;
49545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
50545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    @BeforeExperiment
51545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    protected void setUp() throws Exception {
52a09b4d2a611a7606e8fc8c73a24bd941b6fc173fNarayan Kamath        int copyAmount = Integer.parseInt(mParamCopyAmount);
53545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        StringBuilder strBuilder = new StringBuilder();
54545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        for (int i = 0; i < copyAmount; i++) {
55545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir            strBuilder.append(mParamBasicText);
56545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        }
57545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        mTestSpannable = new SpannableString(strBuilder.toString());
58545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    }
59545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
60545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    @AfterExperiment
61545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    protected void tearDown() {
62545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        mTestSpannable = null;
63545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    }
64545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
65545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    @Benchmark
66545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    public void timeNewRegEx(int reps) throws Exception {
67545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        for (int i = 0; i < reps; i++) {
68545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir            Linkify.addLinks(mTestSpannable, Patterns.AUTOLINK_WEB_URL, "http://",
69545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir                    new String[]{"http://", "https://", "rtsp://"}, null, null);
70545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        }
71545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    }
72545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
73545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    @Benchmark
74545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    public void timeOldRegEx(int reps) throws Exception {
75545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        for (int i = 0; i < reps; i++) {
76545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir            Linkify.addLinks(mTestSpannable, Patterns.WEB_URL, "http://",
77545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir                    new String[]{"http://", "https://", "rtsp://"}, null, null);
78545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        }
79545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    }
80545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
81545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    @Benchmark
82545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    public void timeBasicRegEx(int reps) throws Exception {
83545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        for (int i = 0; i < reps; i++) {
84545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir            Linkify.addLinks(mTestSpannable, BASIC_PATTERN, "http://",
85545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir                    new String[]{"http://", "https://", "rtsp://"}, null, null);
86545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir        }
87545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir    }
88545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir
89545c3cf95ffc46a81e7680f37e4d55eaa8622b32Siyamed Sinir}
90