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