xref: /aosp_15_r20/external/perfetto/src/trace_processor/db/query_executor_benchmark.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
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 
17 #include <benchmark/benchmark.h>
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <initializer_list>
22 #include <optional>
23 #include <string>
24 #include <string_view>
25 #include <vector>
26 
27 #include "perfetto/base/logging.h"
28 #include "perfetto/ext/base/file_utils.h"
29 #include "perfetto/ext/base/string_utils.h"
30 #include "perfetto/ext/base/string_view.h"
31 #include "perfetto/trace_processor/basic_types.h"
32 #include "src/base/test/utils.h"
33 #include "src/trace_processor/containers/string_pool.h"
34 #include "src/trace_processor/db/column/types.h"
35 #include "src/trace_processor/db/table.h"
36 #include "src/trace_processor/tables/metadata_tables_py.h"
37 #include "src/trace_processor/tables/profiler_tables_py.h"
38 #include "src/trace_processor/tables/slice_tables_py.h"
39 #include "src/trace_processor/tables/track_tables_py.h"
40 
41 namespace perfetto::trace_processor {
42 namespace {
43 
44 using SliceTable = tables::SliceTable;
45 using ThreadTrackTable = tables::ThreadTrackTable;
46 using ExpectedFrameTimelineSliceTable = tables::ExpectedFrameTimelineSliceTable;
47 using RawTable = tables::RawTable;
48 using FtraceEventTable = tables::FtraceEventTable;
49 using HeapGraphObjectTable = tables::HeapGraphObjectTable;
50 
51 // `SELECT * FROM SLICE` on android_monitor_contention_trace.at
52 constexpr std::string_view kSliceTable =
53     "test/data/slice_table_for_benchmarks.csv";
54 
55 // `SELECT * FROM SLICE` on android_monitor_contention_trace.at
56 constexpr std::string_view kExpectedFrameTimelineTable =
57     "test/data/expected_frame_timeline_for_benchmarks.csv";
58 
59 // `SELECT id, cpu FROM raw` on chrome_android_systrace.pftrace.
60 constexpr std::string_view kRawTable = "test/data/raw_cpu_for_benchmarks.csv";
61 
62 // `SELECT id, cpu FROM ftrace_event` on chrome_android_systrace.pftrace.
63 constexpr std::string_view kFtraceEventTable =
64     "test/data/ftrace_event_cpu_for_benchmarks.csv";
65 
66 // `SELECT id, upid, reference_set_id FROM heap_graph_object` on
67 constexpr std::string_view kHeapGraphObjectTable =
68     "test/data/heap_pgraph_object_for_benchmarks_query.csv";
69 
SplitCSVLine(const std::string & line)70 std::vector<std::string> SplitCSVLine(const std::string& line) {
71   std::vector<std::string> output;
72   uint32_t start = 0;
73   bool in_string = false;
74 
75   for (uint32_t i = 0; i < line.size(); ++i) {
76     if (!in_string && line[i] == ',') {
77       output.emplace_back(&line[start], i - start);
78       start = i + 1;
79       continue;
80     }
81     if (line[i] == '"')
82       in_string = !in_string;
83   }
84 
85   if (start < line.size())
86     output.emplace_back(&line[start], line.size() - start);
87 
88   return output;
89 }
90 
ReadCSV(benchmark::State & state,std::string_view file_name)91 std::vector<std::string> ReadCSV(benchmark::State& state,
92                                  std::string_view file_name) {
93   std::string table_csv;
94   perfetto::base::ReadFile(
95       perfetto::base::GetTestDataPath(std::string(file_name)), &table_csv);
96   if (table_csv.empty()) {
97     state.SkipWithError(
98         "Test strings missing. Googlers: download "
99         "go/perfetto-benchmark-trace-strings and save into /tmp/trace_strings");
100     return {};
101   }
102   PERFETTO_CHECK(!table_csv.empty());
103   return base::SplitString(table_csv, "\n");
104 }
105 
106 template <typename It>
CountRows(It it)107 double CountRows(It it) {
108   double i = 0;
109   for (; it; ++it, ++i) {
110   }
111   return i;
112 }
113 
StripAndIntern(StringPool & pool,const std::string & data)114 StringPool::Id StripAndIntern(StringPool& pool, const std::string& data) {
115   std::string res = base::StripSuffix(base::StripPrefix(data, "\""), "\"");
116   return pool.InternString(base::StringView(res));
117 }
118 
GetSliceTableRow(const std::string & string_row,StringPool & pool)119 SliceTable::Row GetSliceTableRow(const std::string& string_row,
120                                  StringPool& pool) {
121   std::vector<std::string> row_vec = SplitCSVLine(string_row);
122   SliceTable::Row row;
123   PERFETTO_CHECK(row_vec.size() >= 14);
124   row.ts = *base::StringToInt64(row_vec[2]);
125   row.dur = *base::StringToInt64(row_vec[3]);
126   row.track_id = ThreadTrackTable::Id(*base::StringToUInt32(row_vec[4]));
127   row.category = StripAndIntern(pool, row_vec[5]);
128   row.name = StripAndIntern(pool, row_vec[6]);
129   row.depth = *base::StringToUInt32(row_vec[7]);
130   row.stack_id = *base::StringToInt32(row_vec[8]);
131   row.parent_stack_id = *base::StringToInt32(row_vec[9]);
132   row.parent_id = base::StringToUInt32(row_vec[10]).has_value()
133                       ? std::make_optional<SliceTable::Id>(
134                             *base::StringToUInt32(row_vec[10]))
135                       : std::nullopt;
136   row.arg_set_id = *base::StringToUInt32(row_vec[11]);
137   row.thread_ts = base::StringToInt64(row_vec[12]);
138   row.thread_dur = base::StringToInt64(row_vec[13]);
139   return row;
140 }
141 
142 struct SliceTableForBenchmark {
SliceTableForBenchmarkperfetto::trace_processor::__anon499c33ea0111::SliceTableForBenchmark143   explicit SliceTableForBenchmark(benchmark::State& state) : table_{&pool_} {
144     std::vector<std::string> rows_strings = ReadCSV(state, kSliceTable);
145 
146     for (size_t i = 1; i < rows_strings.size(); ++i) {
147       table_.Insert(GetSliceTableRow(rows_strings[i], pool_));
148     }
149   }
150 
151   StringPool pool_;
152   SliceTable table_;
153 };
154 
155 struct ExpectedFrameTimelineTableForBenchmark {
ExpectedFrameTimelineTableForBenchmarkperfetto::trace_processor::__anon499c33ea0111::ExpectedFrameTimelineTableForBenchmark156   explicit ExpectedFrameTimelineTableForBenchmark(benchmark::State& state)
157       : table_{&pool_, &parent_} {
158     std::vector<std::string> table_rows_as_string =
159         ReadCSV(state, kExpectedFrameTimelineTable);
160     std::vector<std::string> parent_rows_as_string =
161         ReadCSV(state, kSliceTable);
162 
163     uint32_t cur_idx = 0;
164     for (size_t i = 1; i < table_rows_as_string.size(); ++i, ++cur_idx) {
165       std::vector<std::string> row_vec = SplitCSVLine(table_rows_as_string[i]);
166 
167       uint32_t idx = *base::StringToUInt32(row_vec[0]);
168       while (cur_idx < idx) {
169         parent_.Insert(
170             GetSliceTableRow(parent_rows_as_string[cur_idx + 1], pool_));
171         cur_idx++;
172       }
173 
174       ExpectedFrameTimelineSliceTable::Row row;
175       row.ts = *base::StringToInt64(row_vec[2]);
176       row.dur = *base::StringToInt64(row_vec[3]);
177       row.track_id = ThreadTrackTable::Id(*base::StringToUInt32(row_vec[4]));
178       row.depth = *base::StringToUInt32(row_vec[7]);
179       row.stack_id = *base::StringToInt32(row_vec[8]);
180       row.parent_stack_id = *base::StringToInt32(row_vec[9]);
181       row.parent_id = base::StringToUInt32(row_vec[11]).has_value()
182                           ? std::make_optional<SliceTable::Id>(
183                                 *base::StringToUInt32(row_vec[11]))
184                           : std::nullopt;
185       row.arg_set_id = *base::StringToUInt32(row_vec[11]);
186       row.thread_ts = base::StringToInt64(row_vec[12]);
187       row.thread_dur = base::StringToInt64(row_vec[13]);
188       table_.Insert(row);
189     }
190   }
191   StringPool pool_;
192   SliceTable parent_{&pool_};
193   ExpectedFrameTimelineSliceTable table_;
194 };
195 
196 struct FtraceEventTableForBenchmark {
FtraceEventTableForBenchmarkperfetto::trace_processor::__anon499c33ea0111::FtraceEventTableForBenchmark197   explicit FtraceEventTableForBenchmark(benchmark::State& state) {
198     std::vector<std::string> raw_rows = ReadCSV(state, kRawTable);
199     std::vector<std::string> ftrace_event_rows =
200         ReadCSV(state, kFtraceEventTable);
201 
202     uint32_t cur_idx = 0;
203     for (size_t i = 1; i < ftrace_event_rows.size(); ++i, cur_idx++) {
204       std::vector<std::string> row_vec = SplitCSVLine(ftrace_event_rows[i]);
205       uint32_t idx = *base::StringToUInt32(row_vec[0]);
206       while (cur_idx < idx) {
207         std::vector<std::string> raw_row = SplitCSVLine(raw_rows[cur_idx + 1]);
208         RawTable::Row r;
209         r.ucpu = tables::CpuTable::Id(*base::StringToUInt32(raw_row[1]));
210         raw_.Insert(r);
211         cur_idx++;
212       }
213       FtraceEventTable::Row row;
214       row.ucpu = tables::CpuTable::Id(*base::StringToUInt32(row_vec[1]));
215       table_.Insert(row);
216     }
217   }
218 
219   StringPool pool_;
220   RawTable raw_{&pool_};
221   tables::FtraceEventTable table_{&pool_, &raw_};
222 };
223 
224 struct HeapGraphObjectTableForBenchmark {
HeapGraphObjectTableForBenchmarkperfetto::trace_processor::__anon499c33ea0111::HeapGraphObjectTableForBenchmark225   explicit HeapGraphObjectTableForBenchmark(benchmark::State& state) {
226     std::vector<std::string> table_rows_as_string =
227         ReadCSV(state, kHeapGraphObjectTable);
228 
229     for (size_t i = 1; i < table_rows_as_string.size(); ++i) {
230       std::vector<std::string> row_vec = SplitCSVLine(table_rows_as_string[i]);
231 
232       HeapGraphObjectTable::Row row;
233       row.upid = *base::StringToUInt32(row_vec[1]);
234       row.reference_set_id = base::StringToUInt32(row_vec[2]);
235       table_.Insert(row);
236     }
237   }
238   StringPool pool_;
239   HeapGraphObjectTable table_{&pool_};
240 };
241 
BenchmarkSliceTableFilter(benchmark::State & state,SliceTableForBenchmark & table,std::initializer_list<Constraint> c)242 void BenchmarkSliceTableFilter(benchmark::State& state,
243                                SliceTableForBenchmark& table,
244                                std::initializer_list<Constraint> c) {
245   Query q;
246   q.constraints = c;
247   for (auto _ : state) {
248     benchmark::DoNotOptimize(table.table_.FilterToIterator(q));
249   }
250   state.counters["s/row"] =
251       benchmark::Counter(static_cast<double>(table.table_.row_count()),
252                          benchmark::Counter::kIsIterationInvariantRate |
253                              benchmark::Counter::kInvert);
254   state.counters["s/out"] =
255       benchmark::Counter(CountRows(table.table_.FilterToIterator(q)),
256                          benchmark::Counter::kIsIterationInvariantRate |
257                              benchmark::Counter::kInvert);
258 }
259 
BenchmarkSliceTableSort(benchmark::State & state,SliceTableForBenchmark & table,std::initializer_list<Order> ob)260 void BenchmarkSliceTableSort(benchmark::State& state,
261                              SliceTableForBenchmark& table,
262                              std::initializer_list<Order> ob) {
263   for (auto _ : state) {
264     benchmark::DoNotOptimize(table.table_.Sort(ob));
265   }
266   state.counters["s/row"] =
267       benchmark::Counter(static_cast<double>(table.table_.row_count()),
268                          benchmark::Counter::kIsIterationInvariantRate |
269                              benchmark::Counter::kInvert);
270 }
271 
BenchmarkExpectedFrameTableQuery(benchmark::State & state,ExpectedFrameTimelineTableForBenchmark & table,Query q)272 void BenchmarkExpectedFrameTableQuery(
273     benchmark::State& state,
274     ExpectedFrameTimelineTableForBenchmark& table,
275     Query q) {
276   for (auto _ : state) {
277     benchmark::DoNotOptimize(table.table_.FilterToIterator(q));
278   }
279   state.counters["s/row"] =
280       benchmark::Counter(static_cast<double>(table.table_.row_count()),
281                          benchmark::Counter::kIsIterationInvariantRate |
282                              benchmark::Counter::kInvert);
283   state.counters["s/out"] =
284       benchmark::Counter(CountRows(table.table_.FilterToIterator(q)),
285                          benchmark::Counter::kIsIterationInvariantRate |
286                              benchmark::Counter::kInvert);
287 }
288 
BenchmarkFtraceEventTableQuery(benchmark::State & state,FtraceEventTableForBenchmark & table,Query q)289 void BenchmarkFtraceEventTableQuery(benchmark::State& state,
290                                     FtraceEventTableForBenchmark& table,
291                                     Query q) {
292   for (auto _ : state) {
293     benchmark::DoNotOptimize(table.table_.FilterToIterator(q));
294   }
295   state.counters["s/row"] =
296       benchmark::Counter(static_cast<double>(table.table_.row_count()),
297                          benchmark::Counter::kIsIterationInvariantRate |
298                              benchmark::Counter::kInvert);
299   state.counters["s/out"] =
300       benchmark::Counter(CountRows(table.table_.FilterToIterator(q)),
301                          benchmark::Counter::kIsIterationInvariantRate |
302                              benchmark::Counter::kInvert);
303 }
304 
BenchmarkFtraceEventTableSort(benchmark::State & state,FtraceEventTableForBenchmark & table,std::initializer_list<Order> ob)305 void BenchmarkFtraceEventTableSort(benchmark::State& state,
306                                    FtraceEventTableForBenchmark& table,
307                                    std::initializer_list<Order> ob) {
308   for (auto _ : state) {
309     benchmark::DoNotOptimize(table.table_.Sort(ob));
310   }
311   state.counters["s/row"] =
312       benchmark::Counter(static_cast<double>(table.table_.row_count()),
313                          benchmark::Counter::kIsIterationInvariantRate |
314                              benchmark::Counter::kInvert);
315 }
316 
BM_QESliceTableTrackIdEq(benchmark::State & state)317 void BM_QESliceTableTrackIdEq(benchmark::State& state) {
318   SliceTableForBenchmark table(state);
319   BenchmarkSliceTableFilter(state, table, {table.table_.track_id().eq(1213)});
320 }
321 BENCHMARK(BM_QESliceTableTrackIdEq);
322 
BM_QESliceTableParentIdIsNotNull(benchmark::State & state)323 void BM_QESliceTableParentIdIsNotNull(benchmark::State& state) {
324   SliceTableForBenchmark table(state);
325   BenchmarkSliceTableFilter(state, table,
326                             {table.table_.parent_id().is_not_null()});
327 }
328 BENCHMARK(BM_QESliceTableParentIdIsNotNull);
329 
BM_QESliceTableParentIdEq(benchmark::State & state)330 void BM_QESliceTableParentIdEq(benchmark::State& state) {
331   SliceTableForBenchmark table(state);
332   BenchmarkSliceTableFilter(state, table, {table.table_.parent_id().eq(26711)});
333 }
334 BENCHMARK(BM_QESliceTableParentIdEq);
335 
BM_QESliceTableNameEq(benchmark::State & state)336 void BM_QESliceTableNameEq(benchmark::State& state) {
337   SliceTableForBenchmark table(state);
338   BenchmarkSliceTableFilter(
339       state, table,
340       {table.table_.name().eq("MarkFromReadBarrierWithMeasurements")});
341 }
342 BENCHMARK(BM_QESliceTableNameEq);
343 
BM_QESliceTableNameGlobNoStars(benchmark::State & state)344 void BM_QESliceTableNameGlobNoStars(benchmark::State& state) {
345   SliceTableForBenchmark table(state);
346   BenchmarkSliceTableFilter(
347       state, table,
348       {table.table_.name().glob("MarkFromReadBarrierWithMeasurements")});
349 }
350 BENCHMARK(BM_QESliceTableNameGlobNoStars);
351 
BM_QESliceTableNameGlob(benchmark::State & state)352 void BM_QESliceTableNameGlob(benchmark::State& state) {
353   SliceTableForBenchmark table(state);
354   BenchmarkSliceTableFilter(
355       state, table, {table.table_.name().glob("HIDL::IMapper::unlock::*")});
356 }
357 BENCHMARK(BM_QESliceTableNameGlob);
358 
BM_QESliceTableNameRegex(benchmark::State & state)359 void BM_QESliceTableNameRegex(benchmark::State& state) {
360   SliceTableForBenchmark table(state);
361   BenchmarkSliceTableFilter(state, table,
362                             {table.table_.name().regex(".*Pool.*")});
363 }
364 BENCHMARK(BM_QESliceTableNameRegex);
365 
BM_QESliceTableSorted(benchmark::State & state)366 void BM_QESliceTableSorted(benchmark::State& state) {
367   SliceTableForBenchmark table(state);
368   BenchmarkSliceTableFilter(state, table,
369                             {table.table_.ts().gt(1738923505854),
370                              table.table_.ts().lt(1738950140556)});
371 }
372 BENCHMARK(BM_QESliceTableSorted);
373 
BM_QEFilterWithSparseSelector(benchmark::State & state)374 void BM_QEFilterWithSparseSelector(benchmark::State& state) {
375   ExpectedFrameTimelineTableForBenchmark table(state);
376   Query q;
377   q.constraints = {table.table_.track_id().eq(1445)};
378   BenchmarkExpectedFrameTableQuery(state, table, q);
379 }
380 BENCHMARK(BM_QEFilterWithSparseSelector);
381 
BM_QEFilterWithDenseSelector(benchmark::State & state)382 void BM_QEFilterWithDenseSelector(benchmark::State& state) {
383   FtraceEventTableForBenchmark table(state);
384   Query q;
385   q.constraints = {table.table_.ucpu().eq(4)};
386   BenchmarkFtraceEventTableQuery(state, table, q);
387 }
388 BENCHMARK(BM_QEFilterWithDenseSelector);
389 
BM_QESliceEventFilterId(benchmark::State & state)390 void BM_QESliceEventFilterId(benchmark::State& state) {
391   SliceTableForBenchmark table(state);
392   BenchmarkSliceTableFilter(state, table, {table.table_.id().eq(500)});
393 }
394 BENCHMARK(BM_QESliceEventFilterId);
395 
BM_QEFtraceEventFilterId(benchmark::State & state)396 void BM_QEFtraceEventFilterId(benchmark::State& state) {
397   FtraceEventTableForBenchmark table(state);
398   Query q;
399   q.constraints = {table.table_.id().eq(500)};
400   BenchmarkFtraceEventTableQuery(state, table, q);
401 }
402 
403 BENCHMARK(BM_QEFtraceEventFilterId);
404 
BM_QESliceTableTsAndTrackId(benchmark::State & state)405 void BM_QESliceTableTsAndTrackId(benchmark::State& state) {
406   SliceTableForBenchmark table(state);
407   BenchmarkSliceTableFilter(
408       state, table,
409       {table.table_.ts().ge(1738923505854), table.table_.ts().le(1738950140556),
410        table.table_.track_id().eq(1422)});
411 }
412 BENCHMARK(BM_QESliceTableTsAndTrackId);
413 
BM_QEFilterOneElement(benchmark::State & state)414 void BM_QEFilterOneElement(benchmark::State& state) {
415   SliceTableForBenchmark table(state);
416   BenchmarkSliceTableFilter(
417       state, table,
418       {table.table_.id().eq(11732), table.table_.track_id().eq(1422)});
419 }
420 BENCHMARK(BM_QEFilterOneElement);
421 
BM_QEFilterWithArrangement(benchmark::State & state)422 void BM_QEFilterWithArrangement(benchmark::State& state) {
423   SliceTableForBenchmark table(state);
424   Order order{table.table_.dur().index_in_table(), false};
425   Table slice_sorted_with_duration = table.table_.Sort({order});
426 
427   Constraint c{table.table_.track_id().index_in_table(), FilterOp::kGt,
428                SqlValue::Long(10)};
429   Query q;
430   q.constraints = {c};
431   for (auto _ : state) {
432     benchmark::DoNotOptimize(slice_sorted_with_duration.QueryToRowMap(q));
433   }
434   state.counters["s/row"] = benchmark::Counter(
435       static_cast<double>(slice_sorted_with_duration.row_count()),
436       benchmark::Counter::kIsIterationInvariantRate |
437           benchmark::Counter::kInvert);
438   state.counters["s/out"] = benchmark::Counter(
439       static_cast<double>(table.table_.QueryToRowMap(q).size()),
440       benchmark::Counter::kIsIterationInvariantRate |
441           benchmark::Counter::kInvert);
442 }
443 BENCHMARK(BM_QEFilterWithArrangement);
444 
BM_QEDenseNullFilter(benchmark::State & state)445 void BM_QEDenseNullFilter(benchmark::State& state) {
446   HeapGraphObjectTableForBenchmark table(state);
447   Constraint c{table.table_.reference_set_id().index_in_table(), FilterOp::kGt,
448                SqlValue::Long(1000)};
449   Query q;
450   q.constraints = {c};
451   for (auto _ : state) {
452     benchmark::DoNotOptimize(table.table_.FilterToIterator(q));
453   }
454   state.counters["s/row"] =
455       benchmark::Counter(static_cast<double>(table.table_.row_count()),
456                          benchmark::Counter::kIsIterationInvariantRate |
457                              benchmark::Counter::kInvert);
458   state.counters["s/out"] =
459       benchmark::Counter(CountRows(table.table_.FilterToIterator(q)),
460                          benchmark::Counter::kIsIterationInvariantRate |
461                              benchmark::Counter::kInvert);
462 }
463 BENCHMARK(BM_QEDenseNullFilter);
464 
BM_QEDenseNullFilterIsNull(benchmark::State & state)465 void BM_QEDenseNullFilterIsNull(benchmark::State& state) {
466   HeapGraphObjectTableForBenchmark table(state);
467   Constraint c{table.table_.reference_set_id().index_in_table(),
468                FilterOp::kIsNull, SqlValue()};
469   Query q;
470   q.constraints = {c};
471   for (auto _ : state) {
472     benchmark::DoNotOptimize(table.table_.FilterToIterator(q));
473   }
474   state.counters["s/row"] =
475       benchmark::Counter(static_cast<double>(table.table_.row_count()),
476                          benchmark::Counter::kIsIterationInvariantRate |
477                              benchmark::Counter::kInvert);
478   state.counters["s/out"] =
479       benchmark::Counter(CountRows(table.table_.FilterToIterator(q)),
480                          benchmark::Counter::kIsIterationInvariantRate |
481                              benchmark::Counter::kInvert);
482 }
483 BENCHMARK(BM_QEDenseNullFilterIsNull);
484 
BM_QEIdColumnWithIntAsDouble(benchmark::State & state)485 void BM_QEIdColumnWithIntAsDouble(benchmark::State& state) {
486   SliceTableForBenchmark table(state);
487   Constraint c{table.table_.track_id().index_in_table(), FilterOp::kEq,
488                SqlValue::Double(100)};
489   BenchmarkSliceTableFilter(state, table, {c});
490 }
491 BENCHMARK(BM_QEIdColumnWithIntAsDouble);
492 
BM_QEIdColumnWithDouble(benchmark::State & state)493 void BM_QEIdColumnWithDouble(benchmark::State& state) {
494   SliceTableForBenchmark table(state);
495   Constraint c{table.table_.track_id().index_in_table(), FilterOp::kEq,
496                SqlValue::Double(100.5)};
497   BenchmarkSliceTableFilter(state, table, {c});
498 }
499 BENCHMARK(BM_QEIdColumnWithDouble);
500 
BM_QEFilterOrderedArrangement(benchmark::State & state)501 void BM_QEFilterOrderedArrangement(benchmark::State& state) {
502   SliceTableForBenchmark table(state);
503   Order order{table.table_.dur().index_in_table(), false};
504   Table slice_sorted_with_duration = table.table_.Sort({order});
505 
506   Constraint c{table.table_.dur().index_in_table(), FilterOp::kGt,
507                SqlValue::Long(10)};
508   Query q;
509   q.constraints = {c};
510   for (auto _ : state) {
511     benchmark::DoNotOptimize(slice_sorted_with_duration.QueryToRowMap(q));
512   }
513   state.counters["s/row"] = benchmark::Counter(
514       static_cast<double>(slice_sorted_with_duration.row_count()),
515       benchmark::Counter::kIsIterationInvariantRate |
516           benchmark::Counter::kInvert);
517   state.counters["s/out"] = benchmark::Counter(
518       static_cast<double>(table.table_.QueryToRowMap(q).size()),
519       benchmark::Counter::kIsIterationInvariantRate |
520           benchmark::Counter::kInvert);
521 }
522 BENCHMARK(BM_QEFilterOrderedArrangement);
523 
BM_QEFilterNullOrderedArrangement(benchmark::State & state)524 void BM_QEFilterNullOrderedArrangement(benchmark::State& state) {
525   SliceTableForBenchmark table(state);
526   Order order{table.table_.parent_id().index_in_table(), false};
527   Table slice_sorted_with_parent_id = table.table_.Sort({order});
528 
529   Constraint c{table.table_.parent_id().index_in_table(), FilterOp::kGt,
530                SqlValue::Long(26091)};
531   Query q;
532   q.constraints = {c};
533   for (auto _ : state) {
534     benchmark::DoNotOptimize(slice_sorted_with_parent_id.QueryToRowMap(q));
535   }
536   state.counters["s/row"] = benchmark::Counter(
537       static_cast<double>(slice_sorted_with_parent_id.row_count()),
538       benchmark::Counter::kIsIterationInvariantRate |
539           benchmark::Counter::kInvert);
540   state.counters["s/out"] = benchmark::Counter(
541       static_cast<double>(table.table_.QueryToRowMap(q).size()),
542       benchmark::Counter::kIsIterationInvariantRate |
543           benchmark::Counter::kInvert);
544 }
545 BENCHMARK(BM_QEFilterNullOrderedArrangement);
546 
BM_QESliceFilterIndexSearchOneElement(benchmark::State & state)547 void BM_QESliceFilterIndexSearchOneElement(benchmark::State& state) {
548   SliceTableForBenchmark table(state);
549   BenchmarkSliceTableFilter(
550       state, table,
551       {table.table_.track_id().eq(1422), table.table_.id().eq(11732)});
552 }
553 BENCHMARK(BM_QESliceFilterIndexSearchOneElement);
554 
BM_QESliceFilterIndexSearch(benchmark::State & state)555 void BM_QESliceFilterIndexSearch(benchmark::State& state) {
556   SliceTableForBenchmark table(state);
557   BenchmarkSliceTableFilter(state, table,
558                             {table.table_.track_id().eq(1422),
559                              table.table_.name().eq("notifyFramePending")});
560 }
561 BENCHMARK(BM_QESliceFilterIndexSearch);
562 
BM_QESliceSortNumericAsc(benchmark::State & state)563 void BM_QESliceSortNumericAsc(benchmark::State& state) {
564   SliceTableForBenchmark table(state);
565   BenchmarkSliceTableSort(state, table, {table.table_.track_id().ascending()});
566 }
567 BENCHMARK(BM_QESliceSortNumericAsc);
568 
BM_QESliceSortNullNumericAsc(benchmark::State & state)569 void BM_QESliceSortNullNumericAsc(benchmark::State& state) {
570   SliceTableForBenchmark table(state);
571   BenchmarkSliceTableSort(state, table, {table.table_.parent_id().ascending()});
572 }
573 BENCHMARK(BM_QESliceSortNullNumericAsc);
574 
BM_QEFtraceEventSortSelectorNumericAsc(benchmark::State & state)575 void BM_QEFtraceEventSortSelectorNumericAsc(benchmark::State& state) {
576   FtraceEventTableForBenchmark table(state);
577   BenchmarkFtraceEventTableSort(state, table,
578                                 {table.table_.ucpu().ascending()});
579 }
580 BENCHMARK(BM_QEFtraceEventSortSelectorNumericAsc);
581 
BM_QEFtraceEventSortSelectorNumericDesc(benchmark::State & state)582 void BM_QEFtraceEventSortSelectorNumericDesc(benchmark::State& state) {
583   FtraceEventTableForBenchmark table(state);
584   BenchmarkFtraceEventTableSort(state, table,
585                                 {table.table_.ucpu().descending()});
586 }
587 BENCHMARK(BM_QEFtraceEventSortSelectorNumericDesc);
588 
BM_QEDistinctWithSparseSelector(benchmark::State & state)589 void BM_QEDistinctWithSparseSelector(benchmark::State& state) {
590   ExpectedFrameTimelineTableForBenchmark table(state);
591   Query q;
592   q.order_type = Query::OrderType::kDistinct;
593   q.orders = {table.table_.track_id().descending()};
594   BenchmarkExpectedFrameTableQuery(state, table, q);
595 }
596 BENCHMARK(BM_QEDistinctWithSparseSelector);
597 
BM_QEDistinctWithDenseSelector(benchmark::State & state)598 void BM_QEDistinctWithDenseSelector(benchmark::State& state) {
599   FtraceEventTableForBenchmark table(state);
600   Query q;
601   q.order_type = Query::OrderType::kDistinct;
602   q.orders = {table.table_.ucpu().descending()};
603   BenchmarkFtraceEventTableQuery(state, table, q);
604 }
605 BENCHMARK(BM_QEDistinctWithDenseSelector);
606 
BM_QEDistinctSortedWithSparseSelector(benchmark::State & state)607 void BM_QEDistinctSortedWithSparseSelector(benchmark::State& state) {
608   ExpectedFrameTimelineTableForBenchmark table(state);
609   Query q;
610   q.order_type = Query::OrderType::kDistinctAndSort;
611   q.orders = {table.table_.track_id().descending()};
612   BenchmarkExpectedFrameTableQuery(state, table, q);
613 }
614 BENCHMARK(BM_QEDistinctSortedWithSparseSelector);
615 
BM_QEDistinctSortedWithDenseSelector(benchmark::State & state)616 void BM_QEDistinctSortedWithDenseSelector(benchmark::State& state) {
617   FtraceEventTableForBenchmark table(state);
618   Query q;
619   q.order_type = Query::OrderType::kDistinctAndSort;
620   q.orders = {table.table_.ucpu().descending()};
621   BenchmarkFtraceEventTableQuery(state, table, q);
622 }
623 BENCHMARK(BM_QEDistinctSortedWithDenseSelector);
624 
BM_QEDistinctWithArrangement(benchmark::State & state)625 void BM_QEDistinctWithArrangement(benchmark::State& state) {
626   SliceTableForBenchmark table(state);
627   Order order{table.table_.dur().index_in_table(), false};
628   Table slice_sorted_with_duration = table.table_.Sort({order});
629 
630   Query q;
631   q.order_type = Query::OrderType::kDistinct;
632   q.orders = {table.table_.track_id().descending()};
633 
634   for (auto _ : state) {
635     benchmark::DoNotOptimize(slice_sorted_with_duration.QueryToRowMap(q));
636   }
637   state.counters["s/row"] = benchmark::Counter(
638       static_cast<double>(slice_sorted_with_duration.row_count()),
639       benchmark::Counter::kIsIterationInvariantRate |
640           benchmark::Counter::kInvert);
641   state.counters["s/out"] = benchmark::Counter(
642       static_cast<double>(table.table_.QueryToRowMap(q).size()),
643       benchmark::Counter::kIsIterationInvariantRate |
644           benchmark::Counter::kInvert);
645 }
646 BENCHMARK(BM_QEDistinctWithArrangement);
647 
BM_QEDistinctSortedWithArrangement(benchmark::State & state)648 void BM_QEDistinctSortedWithArrangement(benchmark::State& state) {
649   SliceTableForBenchmark table(state);
650   Order order{table.table_.dur().index_in_table(), false};
651   Table slice_sorted_with_duration = table.table_.Sort({order});
652 
653   Query q;
654   q.order_type = Query::OrderType::kDistinctAndSort;
655   q.orders = {table.table_.track_id().descending()};
656 
657   for (auto _ : state) {
658     benchmark::DoNotOptimize(slice_sorted_with_duration.QueryToRowMap(q));
659   }
660   state.counters["s/row"] = benchmark::Counter(
661       static_cast<double>(slice_sorted_with_duration.row_count()),
662       benchmark::Counter::kIsIterationInvariantRate |
663           benchmark::Counter::kInvert);
664   state.counters["s/out"] = benchmark::Counter(
665       static_cast<double>(table.table_.QueryToRowMap(q).size()),
666       benchmark::Counter::kIsIterationInvariantRate |
667           benchmark::Counter::kInvert);
668 }
669 BENCHMARK(BM_QEDistinctSortedWithArrangement);
670 
BM_QEOffsetLimit(benchmark::State & state)671 void BM_QEOffsetLimit(benchmark::State& state) {
672   FtraceEventTableForBenchmark table(state);
673   Query q;
674   q.limit = 10;
675   q.offset = 100;
676   BenchmarkFtraceEventTableQuery(state, table, q);
677 }
678 BENCHMARK(BM_QEOffsetLimit);
679 
BM_QEMax(benchmark::State & state)680 void BM_QEMax(benchmark::State& state) {
681   FtraceEventTableForBenchmark table(state);
682   Query q;
683   q.limit = 1;
684   q.orders = {table.table_.utid().descending()};
685   BenchmarkFtraceEventTableQuery(state, table, q);
686 }
687 BENCHMARK(BM_QEMax);
688 
689 }  // namespace
690 }  // namespace perfetto::trace_processor
691