xref: /aosp_15_r20/external/cronet/base/tracing/stdlib/chrome/speedometer.sql (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1-- Copyright 2023 The Chromium Authors
2-- Use of this source code is governed by a BSD-style license that can be
3-- found in the LICENSE file.
4
5-- Annotates a trace with Speedometer 2.1 related information.
6--
7-- The scripts below analyse traces with the following tracing options
8-- enabled:
9--
10--  - Chromium:
11--      "blink.user_timing".
12--
13--  NOTE: A regular speedometer run (e.g. from the website) will generate the
14--  required events. No need to add any extra JS or anything.
15--
16-- Noteworthy tables:
17--   speedometer_mark: List of marks (event slices) emitted by Speedometer.
18--       These are the points in time Speedometer makes a clock reading to
19--       compute intervals of time for the final score.
20--   speedometer_measure_slice: Augmented slices for Speedometer measurements.
21--       These are the intervals of time Speedometer uses to compute the final
22--       score.
23--   speedometer_iteration_slice: Slice that covers one Speedometer iteration
24--       and has the total_time and score for it. If you average all the scores
25--       over all iterations you get the final Speedometer score for the run.
26
27-- List of marks (event slices) emitted by Speedometer.
28-- These are the points in time Speedometer makes a clock reading to compute
29-- intervals of time for the final score.
30--
31-- @column slice_id      Slice this data refers to.
32-- @column iteration     Speedometer iteration the mark belongs to.
33-- @column suite_name    Suite name
34-- @column test_name     Test name
35-- @column mark_type     Type of mark (start, sync-end, async-end)
36CREATE PERFETTO VIEW _chrome_speedometer_mark
37AS
38WITH
39  speedometer_21_suite_name(suite_name) AS (
40    VALUES
41      ('VanillaJS-TodoMVC'),
42      ('Vanilla-ES2015-TodoMVC'),
43      ('Vanilla-ES2015-Babel-Webpack-TodoMVC'),
44      ('React-TodoMVC'),
45      ('React-Redux-TodoMVC'),
46      ('EmberJS-TodoMVC'),
47      ('EmberJS-Debug-TodoMVC'),
48      ('BackboneJS-TodoMVC'),
49      ('AngularJS-TodoMVC'),
50      ('Angular2-TypeScript-TodoMVC'),
51      ('VueJS-TodoMVC'),
52      ('jQuery-TodoMVC'),
53      ('Preact-TodoMVC'),
54      ('Inferno-TodoMVC'),
55      ('Elm-TodoMVC'),
56      ('Flight-TodoMVC')
57  ),
58  speedometer_21_test_name(test_name) AS (
59    VALUES
60      ('Adding100Items'),
61      ('CompletingAllItems'),
62      -- This seems to be an issue with Speedometer 2.1. All tests delete all items,
63      -- but for some reason the test names do not match for all suites.
64      ('DeletingAllItems'),
65      ('DeletingItems')
66  ),
67  speedometer_21_test_mark_type(mark_type) AS (
68    VALUES
69      ('start'),
70      ('sync-end'),
71      ('async-end')
72  ),
73  -- Make sure we only look at slices with names we expect.
74  speedometer_mark_name AS (
75    SELECT
76      s.suite_name || '.' || t.test_name || '-' || m.mark_type AS name,
77      s.suite_name,
78      t.test_name,
79      m.mark_type
80    FROM
81      speedometer_21_suite_name AS s,
82      speedometer_21_test_name AS t,
83      speedometer_21_test_mark_type AS m
84  )
85SELECT
86  s.id AS slice_id,
87  RANK() OVER (PARTITION BY name ORDER BY ts ASC) AS iteration,
88  m.suite_name,
89  m.test_name,
90  m.mark_type
91FROM slice AS s
92JOIN speedometer_mark_name AS m
93  USING (name)
94WHERE category = 'blink.user_timing';
95
96-- Augmented slices for Speedometer measurements.
97-- These are the intervals of time Speedometer uses to compute the final score.
98-- There are two intervals that are measured for every test: sync and async
99-- sync is the time between the start and sync-end marks, async is the time
100-- between the sync-end and async-end marks.
101CREATE PERFETTO TABLE chrome_speedometer_measure(
102  -- Speedometer iteration the mark belongs to.
103  iteration INT,
104  -- Suite name
105  suite_name STRING,
106  -- Test name
107  test_name STRING,
108  -- Type of the measure (sync or async)
109  measure_type STRING,
110  -- Start timestamp of the measure
111  ts INT,
112  -- Duration of the measure
113  dur INT
114)
115AS
116WITH
117  -- Get the 3 test timestamps (start, sync-end, async-end) in one row. Using a
118  -- the LAG window function and partitioning by test. 2 out of the 3 rows
119  -- generated per test will have some NULL ts values.
120  augmented AS (
121    SELECT
122      iteration,
123      suite_name,
124      test_name,
125      ts AS async_end_ts,
126      LAG(ts, 1)
127        OVER (PARTITION BY iteration, suite_name, test_name ORDER BY ts ASC)
128        AS sync_end_ts,
129      LAG(ts, 2)
130        OVER (PARTITION BY iteration, suite_name, test_name ORDER BY ts ASC)
131        AS start_ts,
132      COUNT()
133        OVER (PARTITION BY iteration, suite_name, test_name ORDER BY ts ASC)
134        AS mark_count
135    FROM _chrome_speedometer_mark
136    JOIN slice
137      USING (slice_id)
138  ),
139  filtered AS (
140    SELECT *
141    FROM augmented
142    -- This server 2 purposes: make sure we have all the marks (think truncated
143    -- trace), and remove the NULL ts values due to the LAG window function.
144    WHERE mark_count = 3
145  )
146SELECT
147  iteration,
148  suite_name,
149  test_name,
150  'async' AS measure_type,
151  sync_end_ts AS ts,
152  async_end_ts - sync_end_ts AS dur
153FROM filtered
154UNION ALL
155SELECT
156  iteration,
157  suite_name,
158  test_name,
159  'sync' AS measure_type,
160  start_ts AS ts,
161  sync_end_ts - start_ts AS dur
162FROM filtered;
163
164-- Slice that covers one Speedometer iteration.
165-- This slice is actually estimated as a default Speedometer run will not emit
166-- marks to cover this interval. The metrics associated are the same ones
167-- Speedometer would output, but note we use ns precision (Speedometer uses
168-- ~100us) so the actual values might differ a bit. Also note Speedometer
169-- returns the values in ms these here and in ns.
170CREATE PERFETTO TABLE chrome_speedometer_iteration(
171  -- Speedometer iteration.
172  iteration INT,
173  -- Start timestamp of the iteration
174  ts INT,
175  -- Duration of the iteration
176  dur INT,
177  -- Total duration of the measures in this iteration
178  total INT,
179  -- Average suite duration for this iteration.
180  mean INT,
181  -- Geometric mean of the suite durations for this iteration.
182  geomean INT,
183  -- Speedometer score for this iteration (The total score for a run in the average of all iteration scores).
184  score INT
185) AS
186SELECT
187  iteration,
188  MIN(start) AS ts,
189  MAX(end) - MIN(start) AS dur,
190  SUM(suite_total) AS total,
191  AVG(suite_total)AS mean,
192  -- Compute geometric mean using LN instead of multiplication to prevent
193  -- overflows
194  EXP(AVG(LN(suite_total))) AS geomean,
195  1e9 / EXP(AVG(LN(suite_total))) * 60 / 3 AS score
196FROM
197  (
198    SELECT
199      iteration, SUM(dur) AS suite_total, MIN(ts) AS start, MAX(ts + dur) AS end
200    FROM chrome_speedometer_measure
201    GROUP BY suite_name, iteration
202  )
203GROUP BY iteration;
204