1-- Copyright 2024 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-- List Speedometer 2.1 test marks. Used to find relevant slices. 6CREATE PERFETTO VIEW _chrome_speedometer_2_1_mark_name( 7 -- Expected slice name 8 name STRING, 9 -- Suite name 10 suite_name STRING, 11 -- Test name 12 test_name STRING, 13 -- Mark type 14 mark_type STRING) 15AS 16WITH 17 data(suite_name, test_name) 18 AS ( 19 VALUES('Angular2-TypeScript-TodoMVC', 'Adding100Items'), 20 ('Angular2-TypeScript-TodoMVC', 'CompletingAllItems'), 21 ('Angular2-TypeScript-TodoMVC', 'DeletingItems'), 22 ('AngularJS-TodoMVC', 'Adding100Items'), 23 ('AngularJS-TodoMVC', 'CompletingAllItems'), 24 ('AngularJS-TodoMVC', 'DeletingAllItems'), 25 ('BackboneJS-TodoMVC', 'Adding100Items'), 26 ('BackboneJS-TodoMVC', 'CompletingAllItems'), 27 ('BackboneJS-TodoMVC', 'DeletingAllItems'), 28 ('Elm-TodoMVC', 'Adding100Items'), 29 ('Elm-TodoMVC', 'CompletingAllItems'), 30 ('Elm-TodoMVC', 'DeletingItems'), 31 ('EmberJS-Debug-TodoMVC', 'Adding100Items'), 32 ('EmberJS-Debug-TodoMVC', 'CompletingAllItems'), 33 ('EmberJS-Debug-TodoMVC', 'DeletingItems'), 34 ('EmberJS-TodoMVC', 'Adding100Items'), 35 ('EmberJS-TodoMVC', 'CompletingAllItems'), 36 ('EmberJS-TodoMVC', 'DeletingItems'), 37 ('Flight-TodoMVC', 'Adding100Items'), 38 ('Flight-TodoMVC', 'CompletingAllItems'), 39 ('Flight-TodoMVC', 'DeletingItems'), 40 ('Inferno-TodoMVC', 'Adding100Items'), 41 ('Inferno-TodoMVC', 'CompletingAllItems'), 42 ('Inferno-TodoMVC', 'DeletingItems'), 43 ('Preact-TodoMVC', 'Adding100Items'), 44 ('Preact-TodoMVC', 'CompletingAllItems'), 45 ('Preact-TodoMVC', 'DeletingItems'), 46 ('React-Redux-TodoMVC', 'Adding100Items'), 47 ('React-Redux-TodoMVC', 'CompletingAllItems'), 48 ('React-Redux-TodoMVC', 'DeletingItems'), 49 ('React-TodoMVC', 'Adding100Items'), 50 ('React-TodoMVC', 'CompletingAllItems'), 51 ('React-TodoMVC', 'DeletingAllItems'), 52 ('Vanilla-ES2015-Babel-Webpack-TodoMVC', 'Adding100Items'), 53 ('Vanilla-ES2015-Babel-Webpack-TodoMVC', 'CompletingAllItems'), 54 ('Vanilla-ES2015-Babel-Webpack-TodoMVC', 'DeletingItems'), 55 ('Vanilla-ES2015-TodoMVC', 'Adding100Items'), 56 ('Vanilla-ES2015-TodoMVC', 'CompletingAllItems'), 57 ('Vanilla-ES2015-TodoMVC', 'DeletingItems'), 58 ('VanillaJS-TodoMVC', 'Adding100Items'), 59 ('VanillaJS-TodoMVC', 'CompletingAllItems'), 60 ('VanillaJS-TodoMVC', 'DeletingAllItems'), 61 ('VueJS-TodoMVC', 'Adding100Items'), 62 ('VueJS-TodoMVC', 'CompletingAllItems'), 63 ('VueJS-TodoMVC', 'DeletingAllItems'), 64 ('jQuery-TodoMVC', 'Adding100Items'), 65 ('jQuery-TodoMVC', 'CompletingAllItems'), 66 ('jQuery-TodoMVC', 'DeletingAllItems') 67 ), 68 mark_type(mark_type) AS (VALUES('start'), ('sync-end'), ('async-end')) 69SELECT 70 suite_name || '.' || test_name || '-' || mark_type AS name, 71 suite_name, 72 test_name, 73 mark_type 74FROM data, mark_type; 75 76-- Augmented slices for Speedometer measurements. 77-- These are the intervals of time Speedometer uses to compute the final score. 78-- There are two intervals that are measured for every test: sync and async 79-- sync is the time between the start and sync-end marks, async is the time 80-- between the sync-end and async-end marks. 81CREATE PERFETTO TABLE chrome_speedometer_2_1_measure( 82 -- Start timestamp of the measure slice 83 ts TIMESTAMP, 84 -- Duration of the measure slice 85 dur DURATION, 86 -- Full measure name 87 name STRING, 88 -- Speedometer iteration the slice belongs to. 89 iteration LONG, 90 -- Suite name 91 suite_name STRING, 92 -- Test name 93 test_name STRING, 94 -- Type of the measure (sync or async) 95 measure_type STRING) 96AS 97WITH 98 mark AS ( 99 SELECT 100 s.id AS slice_id, 101 RANK() OVER (PARTITION BY name ORDER BY ts ASC) AS iteration, 102 m.suite_name, 103 m.test_name, 104 m.mark_type 105 FROM slice AS s 106 -- Make sure we only look at slices with names we expect. 107 JOIN _chrome_speedometer_2_1_mark_name AS m 108 USING (name) 109 WHERE category = 'blink.user_timing' 110 ), 111 -- Get the 3 test timestamps (start, sync-end, async-end) in one row. Using a 112 -- the LAG window function and partitioning by test. 2 out of the 3 rows 113 -- generated per test will have some NULL ts values. 114 augmented AS ( 115 SELECT 116 iteration, 117 suite_name, 118 test_name, 119 ts AS async_end_ts, 120 LAG(ts, 1) 121 OVER (PARTITION BY iteration, suite_name, test_name ORDER BY ts ASC) 122 AS sync_end_ts, 123 LAG(ts, 2) 124 OVER (PARTITION BY iteration, suite_name, test_name ORDER BY ts ASC) 125 AS start_ts, 126 COUNT() 127 OVER (PARTITION BY iteration, suite_name, test_name ORDER BY ts ASC) 128 AS mark_count 129 FROM mark 130 JOIN slice 131 USING (slice_id) 132 ), 133 filtered AS ( 134 SELECT * 135 FROM augmented 136 -- This server 2 purposes: make sure we have all the marks (think truncated 137 -- trace), and remove the NULL ts values due to the LAG window function. 138 WHERE mark_count = 3 139 ), 140 base AS ( 141 SELECT 142 sync_end_ts AS ts, 143 async_end_ts - sync_end_ts AS dur, 144 iteration, 145 suite_name, 146 test_name, 147 'async' AS measure_type 148 FROM filtered 149 UNION ALL 150 SELECT 151 start_ts AS ts, 152 sync_end_ts - start_ts AS dur, 153 iteration, 154 suite_name, 155 test_name, 156 'sync' AS measure_type 157 FROM filtered 158 ) 159SELECT 160 ts, 161 dur, 162 suite_name || '.' || test_name || '-' || measure_type AS name, 163 iteration, 164 suite_name, 165 test_name, 166 measure_type 167FROM base; 168 169-- Slice that covers one Speedometer iteration. 170-- This slice is actually estimated as a default Speedometer run will not emit 171-- marks to cover this interval. The metrics associated are the same ones 172-- Speedometer would output, but note we use ns precision (Speedometer uses 173-- ~100us) so the actual values might differ a bit. Also note Speedometer 174-- returns the values in ms these here and in ns. 175CREATE PERFETTO TABLE chrome_speedometer_2_1_iteration( 176 -- Start timestamp of the iteration 177 ts TIMESTAMP, 178 -- Duration of the iteration 179 dur DURATION, 180 -- Iteration name 181 name STRING, 182 -- Iteration number 183 iteration LONG, 184 -- Geometric mean of the suite durations for this iteration. 185 geomean DOUBLE, 186 -- Speedometer score for this iteration (The total score for a run in the 187 -- average of all iteration scores). 188 score DOUBLE) 189AS 190SELECT 191 MIN(start) AS ts, 192 MAX(END) - MIN(start) AS dur, 193 'iteration-' || iteration AS name, 194 iteration, 195 -- Compute geometric mean using LN instead of multiplication to prevent 196 -- overflows 197 EXP(AVG(LN(suite_total))) AS geomean, 198 1000 / EXP(AVG(LN(suite_total))) * 60 / 3 AS score 199FROM 200 ( 201 SELECT 202 iteration, 203 SUM(dur / (1000.0 * 1000.0)) AS suite_total, 204 MIN(ts) AS start, 205 MAX(ts + dur) AS END 206 FROM chrome_speedometer_2_1_measure 207 GROUP BY suite_name, iteration 208 ) 209GROUP BY iteration; 210 211-- Returns the Speedometer 2.1 score for all iterations in the trace 212CREATE PERFETTO FUNCTION chrome_speedometer_2_1_score() 213-- Speedometer 2.1 score 214RETURNS DOUBLE 215AS 216SELECT AVG(score) FROM chrome_speedometer_2_1_iteration; 217 218-- Returns the utid for the main thread that ran Speedometer 2.1 219CREATE PERFETTO FUNCTION chrome_speedometer_2_1_renderer_main_utid() 220-- Renderer main utid 221RETURNS LONG 222AS 223SELECT utid 224FROM thread_track 225WHERE 226 id IN ( 227 SELECT track_id 228 FROM slice, _chrome_speedometer_2_1_mark_name 229 USING (name) 230 WHERE category = 'blink.user_timing' 231 ); 232