Commit a7f0b818 authored by Mikhail Khokhlov's avatar Mikhail Khokhlov Committed by Commit Bot

[tools/perf] Use window functions to speed up queries

Now that trace_processor_shell built from Chrome supports windows
functions, we can take advantage of them.

Bug: b/150125501
Change-Id: I7e6c93b7b570003c1fc97fda7bbb63cbb388b419
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2107483
Commit-Queue: Mikhail Khokhlov <khokhlov@google.com>
Reviewed-by: default avatarStephen Nusko <nuskos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751292}
parent 3f6b001d
......@@ -18,10 +18,9 @@
-- Get the GestureScrollUpdate events by name ordered by timestamp, compute
-- the number of frames (relative to 60 fps) that each event took. 1.6e+7 is
-- 16 ms in nanoseconds.
-- Note that here and further below the result is a table not a view because
-- it speeds up the metric computation.
CREATE TABLE GestureScrollUpdates AS
CREATE VIEW GestureScrollUpdates AS
SELECT
ROW_NUMBER() OVER (ORDER BY ts ASC) AS rowNumber,
id AS ScrollId,
ts AS ScrollTs,
arg_set_id AS ScrollArgSetId,
......@@ -34,23 +33,13 @@ WHERE
name = 'InputLatency::GestureScrollUpdate'
ORDER BY ScrollTs;
-- TODO(khokhlov): This is pretty slow and should be rewritten using window
-- functions when they are enabled in Chrome's sqlite.
CREATE TABLE GestureScrollUpdatesWithRowNumbers AS
SELECT
(SELECT COUNT(*)
FROM GestureScrollUpdates prev
WHERE prev.ScrollTs < next.ScrollTs) + 1 as rowNumber,
*
FROM
GestureScrollUpdates next;
-- This takes the GestureScrollUpdate and joins it to the previous row (NULL
-- if there isn't one) and the next row (NULL if there isn't one). And then
-- computes whether the duration of the event (relative to 60 fps) varied by
-- more than 0.5 (which is 1/2 of 16 ms).
CREATE TABLE ScrollJanksComplete AS
CREATE VIEW ScrollJanksComplete AS
SELECT
ROW_NUMBER() OVER (ORDER BY currTs ASC) AS rowNumber,
currScrollId,
currTs,
currScrollFramesExact,
......@@ -83,23 +72,12 @@ FROM (
curr.ScrollFramesExact AS currScrollFramesExact,
prev.ScrollFramesExact AS prevScrollFramesExact
FROM
GestureScrollUpdatesWithRowNumbers curr LEFT JOIN
GestureScrollUpdatesWithRowNumbers prev ON prev.rowNumber + 1 = curr.rowNumber
GestureScrollUpdates curr LEFT JOIN
GestureScrollUpdates prev ON prev.rowNumber + 1 = curr.rowNumber
) currprev JOIN
GestureScrollUpdatesWithRowNumbers next ON currprev.currRowNumber + 1 = next.rowNumber
GestureScrollUpdates next ON currprev.currRowNumber + 1 = next.rowNumber
ORDER BY currprev.currTs ASC;
-- TODO(khokhlov): This is pretty slow and should be rewritten using window
-- functions when they are enabled in Chrome's sqlite.
CREATE TABLE ScrollJanksCompleteWithRowNumbers AS
SELECT
(SELECT COUNT(*)
FROM ScrollJanksComplete prev
WHERE prev.currTs < next.currTs) + 1 as rowNumber,
*
FROM
ScrollJanksComplete next;
-- This just lists outs the rowNumber (which is ordered by timestamp) and
-- whether it was a janky slice (as defined by comparing to both the next and
-- previous slice).
......@@ -110,7 +88,7 @@ CREATE VIEW ScrollJanks AS
(nextJank AND prevJank IS NULL) OR
(prevJank AND nextJank IS NULL)
AS Jank
FROM ScrollJanksCompleteWithRowNumbers;
FROM ScrollJanksComplete;
-- This sums the number of periods with sequential janky slices. When Chrome
-- experiences a jank it often stumbles for a while, this attempts to
......
......@@ -46,10 +46,11 @@
-- IDs to group them together into scrolls later and the timestamp and duration
-- to compute the duration of the scroll.
DROP TABLE IF EXISTS ScrollBeginsAndEnds;
DROP VIEW IF EXISTS ScrollBeginsAndEnds;
CREATE TABLE ScrollBeginsAndEnds AS
CREATE VIEW ScrollBeginsAndEnds AS
SELECT
ROW_NUMBER() OVER (ORDER BY ts ASC) AS rowNumber,
name,
id AS scrollId,
ts AS scrollTs,
......@@ -63,31 +64,17 @@ CREATE TABLE ScrollBeginsAndEnds AS
)
ORDER BY ts ASC;
-- TODO(nuskos): Once chromium TBMv3 supports windowing functions use
-- ROW_NUMBER(ORDER BY ts ASC) OVER() instead.
DROP TABLE IF EXISTS ScrollBeginsAndEndsRowNumbers;
CREATE TABLE ScrollBeginsAndEndsRowNumbers AS
SELECT
(SELECT COUNT(*)
FROM ScrollBeginsAndEnds prev
WHERE prev.scrollTs < next.scrollTs) + 1 as rowNumber,
*
FROM
ScrollBeginsAndEnds next;
-- Now we take the Begin and the End events and join the information into a
-- single row per scroll.
DROP TABLE IF EXISTS JoinedScrollBeginsAndEnds;
DROP VIEW IF EXISTS JoinedScrollBeginsAndEnds;
CREATE TABLE JoinedScrollBeginsAndEnds AS
CREATE VIEW JoinedScrollBeginsAndEnds AS
SELECT
begin.scrollId AS beginId,
begin.scrollTs AS scrollBegin,
end.scrollTs + end.scrollDur AS maybeScrollEnd
FROM ScrollBeginsAndEndsRowNumbers begin JOIN ScrollBeginsAndEndsRowNumbers end ON
FROM ScrollBeginsAndEnds begin JOIN ScrollBeginsAndEnds end ON
begin.rowNumber + 1 = end.rowNumber AND
begin.name = 'InputLatency::GestureScrollBegin' AND
end.name = 'InputLatency::GestureScrollEnd';
......@@ -101,10 +88,11 @@ CREATE TABLE JoinedScrollBeginsAndEnds AS
-- and can't reasonably determine what it should be. We have separate tracking
-- to ensure this only happens at the end of the trace.
DROP TABLE IF EXISTS GestureScrollUpdates;
DROP VIEW IF EXISTS GestureScrollUpdates;
CREATE TABLE GestureScrollUpdates AS
CREATE VIEW GestureScrollUpdates AS
SELECT
ROW_NUMBER() OVER (ORDER BY ts ASC) AS rowNumber,
beginId,
scrollBegin,
CASE WHEN
......@@ -139,21 +127,6 @@ FROM JoinedScrollBeginsAndEnds beginAndEnd LEFT JOIN (
scrollUpdate.ts >= beginAndEnd.ScrollBegin
ORDER BY ts ASC;
-- TODO(nuskos): Once chromium TBMv3 supports windowing functions use
-- ROW_NUMBER(ORDER BY ts ASC) OVER() instead.
DROP TABLE IF EXISTS GestureScrollUpdatesRowNumbers;
CREATE TABLE GestureScrollUpdatesRowNumbers AS
SELECT
(SELECT COUNT(*)
FROM GestureScrollUpdates prev
WHERE prev.scrollTs < next.scrollTs) + 1 as rowNumber,
*
FROM
GestureScrollUpdates next;
-- This takes the GestureScrollUpdate and joins it to the previous row (NULL
-- if there isn't one) and the next row (NULL if there isn't one). And then
-- computes if the duration of the event (relative to 60 fps) increased by more
......@@ -164,10 +137,11 @@ FROM
-- (currBeginId == prev/next BeginId). This controls somewhat for variability
-- of scrolls.
DROP TABLE IF EXISTS ScrollJanksMaybeNull;
DROP VIEW IF EXISTS ScrollJanksMaybeNull;
CREATE TABLE ScrollJanksMaybeNull AS
CREATE VIEW ScrollJanksMaybeNull AS
SELECT
ROW_NUMBER() OVER (ORDER BY currScrollTs ASC) AS rowNumber,
currBeginId,
currUpdateDur,
currScrollDur,
......@@ -198,35 +172,19 @@ CREATE TABLE ScrollJanksMaybeNull AS
prev.beginId as prevBeginId,
prev.scrollFramesExact AS prevScrollFramesExact
FROM
GestureScrollUpdatesRowNumbers curr LEFT JOIN
GestureScrollUpdatesRowNumbers prev ON prev.rowNumber + 1 = curr.rowNumber
GestureScrollUpdates curr LEFT JOIN
GestureScrollUpdates prev ON prev.rowNumber + 1 = curr.rowNumber
) currprev JOIN
GestureScrollUpdatesRowNumbers next ON currprev.currRowNumber + 1 = next.rowNumber
GestureScrollUpdates next ON currprev.currRowNumber + 1 = next.rowNumber
ORDER BY currprev.currScrollTs ASC;
-- TODO(nuskos): Once chromium TBMv3 supports windowing functions use
-- ROW_NUMBER(ORDER BY ts ASC) OVER() instead.
DROP TABLE IF EXISTS ScrollJanksMaybeNullRowNumbers;
CREATE TABLE ScrollJanksMaybeNullRowNumbers AS
SELECT
(SELECT COUNT(*)
FROM ScrollJanksMaybeNull prev
WHERE prev.currScrollTs < next.currScrollTs) + 1 as rowNumber,
*
FROM
ScrollJanksMaybeNull next;
-- This just lists outs the rowNumber (which is ordered by timestamp), its jank
-- status and information about the update and scroll overall. Basically
-- getting it into a next queriable format.
DROP TABLE IF EXISTS ScrollJanks;
DROP VIEW IF EXISTS ScrollJanks;
CREATE TABLE ScrollJanks AS
CREATE VIEW ScrollJanks AS
SELECT
rowNumber,
currBeginId,
......@@ -235,7 +193,7 @@ CREATE TABLE ScrollJanks AS
(nextJank IS NOT NULL AND nextJank) OR
(prevJank IS NOT NULL AND prevJank)
AS jank
FROM ScrollJanksMaybeNullRowNumbers;
FROM ScrollJanksMaybeNull;
-- Compute the total amount of nanoseconds from Janky GestureScrollUpdates and
-- the total amount of nanoseconds we spent scrolling in the trace. Also need
......@@ -250,9 +208,9 @@ CREATE TABLE ScrollJanks AS
-- TODO(nuskos): We should support more types (floats and strings) in our
-- metrics as well as support for specifying units (nanoseconds).
DROP TABLE IF EXISTS JankyNanosPerScrollNanosMaybeNull;
DROP VIEW IF EXISTS JankyNanosPerScrollNanosMaybeNull;
CREATE TABLE JankyNanosPerScrollNanosMaybeNull AS
CREATE VIEW JankyNanosPerScrollNanosMaybeNull AS
SELECT
SUM(jank) as numJankyUpdates,
SUM(CASE WHEN jank = 1 THEN
......@@ -270,9 +228,9 @@ CREATE TABLE JankyNanosPerScrollNanosMaybeNull AS
) AS scrollNanos
FROM ScrollJanks;
DROP TABLE IF EXISTS janky_time_per_scroll_processing_time;
DROP VIEW IF EXISTS janky_time_per_scroll_processing_time;
CREATE TABLE janky_time_per_scroll_processing_time AS
CREATE VIEW janky_time_per_scroll_processing_time AS
SELECT
(SELECT
CASE WHEN
......@@ -297,9 +255,9 @@ CREATE TABLE janky_time_per_scroll_processing_time AS
-- Specify how to fill the metrics proto properly.
DROP TABLE IF EXISTS janky_time_per_scroll_processing_time_output;
DROP VIEW IF EXISTS janky_time_per_scroll_processing_time_output;
CREATE TABLE janky_time_per_scroll_processing_time_output AS
CREATE VIEW janky_time_per_scroll_processing_time_output AS
SELECT JankyTimePerScrollProcessingTime(
'janky_time_per_scroll_processing_time_percentage', jankyPercentage,
'gesture_scroll_milliseconds', CAST(scrollMillis AS INT),
......
......@@ -11,35 +11,22 @@
-- to leave only one of them.
-- TODO(khokhlov): Remove one of these metrics.
-- This selects GestureScrollUpdate events. Note the result is a table not a
-- view to speed up the metric computation.
CREATE TABLE input_latency_events AS
-- This selects GestureScrollUpdate events.
CREATE VIEW input_latency_events AS
SELECT
ts AS start, ts + dur AS finish
FROM slice
WHERE
name = "InputLatency::GestureScrollUpdate";
-- This selects timestamps of finishes of GestureScrollUpdate events, and for
-- each finish, finds the timestamp of the next finish.
-- TODO(khokhlov): This query is pretty slow. Rewrite using window functions
-- when they are enabled in Chrome's sqlite.
CREATE TABLE next_finish AS
SELECT
finish,
(SELECT MIN(next.finish)
FROM input_latency_events next
WHERE next.finish > prev.finish) AS next_finish
FROM input_latency_events prev;
-- Every row of this query is a span from one event finish to the next.
-- Column names 'ts' and 'dur' are as expected by SPAN_JOIN function.
CREATE VIEW intervals_between_finishes AS
SELECT
finish AS ts,
next_finish AS next_ts,
next_finish - finish AS dur
FROM next_finish;
LEAD(finish) OVER (ORDER BY finish) AS next_ts,
LEAD(finish) OVER (ORDER BY finish) - finish AS dur
FROM input_latency_events;
-- Every row of this query marks the start of some GestureScrollUpdate event.
-- Column names 'ts' and 'dur' are as expected by SPAN_JOIN function.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment