/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "src/trace_processor/util/glob.h" #include #include #include #include #include #include "perfetto/ext/base/scoped_file.h" #include "perfetto/ext/base/string_view.h" namespace { using benchmark::Counter; using perfetto::trace_processor::util::GlobMatcher; const char kAndroidGlob[] = "*android*"; const char kLaunchingGlob[] = "launching: *"; const char kChoreographerGlob[] = "Choreographer#doFrame*"; const char kQuestionMarkGlob[] = "Choreo?rapher#doFrame*"; const char kCharClassGlob[] = "Choreo[a-z]rapher#doFrame*"; std::vector LoadTraceStrings(benchmark::State& state) { std::vector strs; // This requires that the user has downloaded the file // go/perfetto-benchmark-slice-strings into /tmp/trace_strings. The file is // too big (220 MB after uncompression) and it's not worth adding it to the // //test/data. Also it contains data from a team member's phone and cannot // be public. perfetto::base::ScopedFstream f(fopen("/tmp/slice_strings", "re")); if (!f) { state.SkipWithError( "Test strings missing. Googlers: download " "go/perfetto-benchmark-slice-strings and save into /tmp/slice_strings"); return strs; } char line[4096]; while (fgets(line, sizeof(line), *f)) { strs.emplace_back(perfetto::base::StringView(line).ToStdString()); } return strs; } template void BM_Glob(benchmark::State& state, Args&&... args) { auto args_tuple = std::make_tuple(std::move(args)...); std::vector strs = LoadTraceStrings(state); GlobMatcher glob = GlobMatcher::FromPattern(std::get<0>(args_tuple)); for (auto _ : state) { for (const std::string& str : strs) { benchmark::DoNotOptimize(glob.Matches(perfetto::base::StringView(str))); } benchmark::ClobberMemory(); } state.counters["str/s"] = Counter(static_cast(strs.size()), Counter::kIsIterationInvariantRate); state.counters["s/str"] = Counter(static_cast(strs.size()), Counter::kIsIterationInvariantRate | Counter::kInvert); } BENCHMARK_CAPTURE(BM_Glob, android, kAndroidGlob); BENCHMARK_CAPTURE(BM_Glob, launching, kLaunchingGlob); BENCHMARK_CAPTURE(BM_Glob, choreographer, kChoreographerGlob); BENCHMARK_CAPTURE(BM_Glob, question_mark, kQuestionMarkGlob); BENCHMARK_CAPTURE(BM_Glob, char_class, kCharClassGlob); template void BM_SqliteGlob(benchmark::State& state, Args&&... args) { auto args_tuple = std::make_tuple(std::move(args)...); const char* glob = std::get<0>(args_tuple); std::vector strs = LoadTraceStrings(state); for (auto _ : state) { for (const std::string& str : strs) benchmark::DoNotOptimize(sqlite3_strglob(glob, str.c_str())); benchmark::ClobberMemory(); } state.counters["str/s"] = Counter(static_cast(strs.size()), Counter::kIsIterationInvariantRate); state.counters["s/str"] = Counter(static_cast(strs.size()), Counter::kIsIterationInvariantRate | Counter::kInvert); } BENCHMARK_CAPTURE(BM_SqliteGlob, android, kAndroidGlob); BENCHMARK_CAPTURE(BM_SqliteGlob, launching, kLaunchingGlob); BENCHMARK_CAPTURE(BM_SqliteGlob, slice, kChoreographerGlob); BENCHMARK_CAPTURE(BM_SqliteGlob, question_mark, kQuestionMarkGlob); BENCHMARK_CAPTURE(BM_SqliteGlob, char_class, kCharClassGlob); } // namespace