Skip to content

Commit 2de22b2

Browse files
committed
Add visualization of compilation sections
1 parent 7a5d761 commit 2de22b2

File tree

4 files changed

+328
-14
lines changed

4 files changed

+328
-14
lines changed

site/frontend/src/pages/compare/compile/table/benchmark-detail.vue

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ import {GraphRenderOpts, renderPlots} from "../../../../graph/render";
1313
import {GraphData, GraphKind, GraphsSelector} from "../../../../graph/data";
1414
import uPlot from "uplot";
1515
import CachegrindCmd from "../../../../components/cachegrind-cmd.vue";
16-
import {COMPILE_DETAIL_GRAPHS_RESOLVER} from "./detail-resolver";
16+
import {
17+
COMPILE_DETAIL_GRAPHS_RESOLVER,
18+
COMPILE_DETAIL_SECTIONS_RESOLVER,
19+
CompileDetailGraphs,
20+
CompileDetailGraphsSelector,
21+
CompileDetailSections,
22+
CompileDetailSectionsSelector,
23+
} from "./detail-resolver";
24+
import CompileSectionsChart from "./sections-chart.vue";
1725
import PerfettoLink from "../../../../components/perfetto-link.vue";
1826
1927
const props = defineProps<{
@@ -97,10 +105,9 @@ function drawCurrentDate(opts: GraphRenderOpts, date: Date) {
97105
};
98106
}
99107
100-
// Render both relative and absolute graphs
101-
async function renderGraphs() {
102-
const {start, end, date} = graphRange.value;
103-
const selector = {
108+
function createGraphsSelector(): CompileDetailGraphsSelector {
109+
const {start, end} = graphRange.value;
110+
return {
104111
benchmark: props.testCase.benchmark,
105112
profile: props.testCase.profile,
106113
scenario: props.testCase.scenario,
@@ -109,8 +116,31 @@ async function renderGraphs() {
109116
end,
110117
kinds: ["percentrelative", "raw"] as GraphKind[],
111118
};
112-
const graphsDetail = await COMPILE_DETAIL_GRAPHS_RESOLVER.load(selector);
113-
if (graphsDetail.commits.length === 0) {
119+
}
120+
121+
async function loadGraphs(): Promise<CompileDetailGraphs> {
122+
return await COMPILE_DETAIL_GRAPHS_RESOLVER.load(createGraphsSelector());
123+
}
124+
125+
function createSectionsSelector(): CompileDetailSectionsSelector {
126+
return {
127+
benchmark: props.testCase.benchmark,
128+
profile: props.testCase.profile,
129+
scenario: props.testCase.scenario,
130+
start: props.baseArtifact.commit,
131+
end: props.artifact.commit,
132+
};
133+
}
134+
135+
async function loadSections(): Promise<CompileDetailSections> {
136+
return await COMPILE_DETAIL_SECTIONS_RESOLVER.load(createSectionsSelector());
137+
}
138+
139+
// Render both relative and absolute graphs
140+
async function renderGraphs(detail: CompileDetailGraphs) {
141+
const selector = createGraphsSelector();
142+
const date = graphRange.value.date;
143+
if (detail.commits.length === 0) {
114144
return;
115145
}
116146
@@ -119,13 +149,13 @@ async function renderGraphs() {
119149
kind: GraphKind
120150
): [GraphData, GraphsSelector] {
121151
const data = {
122-
commits: graphsDetail.commits,
152+
commits: detail.commits,
123153
benchmarks: {
124154
[selector.benchmark]: {
125155
// The server returns profiles capitalized, so we need to match that
126156
// here, so that the graph code can find the expected profile.
127157
[capitalize(selector.profile)]: {
128-
[selector.scenario]: graphsDetail.graphs[index],
158+
[selector.scenario]: detail.graphs[index],
129159
},
130160
},
131161
},
@@ -264,7 +294,15 @@ function changeProfileCommand(event: Event) {
264294
profileCommand.value = target.value as ProfileCommand;
265295
}
266296
267-
onMounted(() => renderGraphs());
297+
const sectionsDetail: Ref<CompileDetailSections | null> = ref(null);
298+
onMounted(() => {
299+
loadGraphs().then((d) => {
300+
renderGraphs(d);
301+
});
302+
loadSections().then((d) => {
303+
sectionsDetail.value = d;
304+
});
305+
});
268306
</script>
269307

270308
<template>
@@ -297,7 +335,7 @@ onMounted(() => renderGraphs());
297335
<tr v-if="(metadata?.iterations ?? null) !== null">
298336
<td>
299337
Iterations
300-
<Tooltip> How many times is the benchmark executed? </Tooltip>
338+
<Tooltip> How many times is the benchmark executed?</Tooltip>
301339
</td>
302340
<td>{{ metadata.iterations }}</td>
303341
</tr>
@@ -391,6 +429,32 @@ onMounted(() => renderGraphs());
391429
<div ref="relativeChartElement"></div>
392430
</div>
393431
</div>
432+
<div class="columns">
433+
<div class="rows grow">
434+
<div class="title bold">
435+
Sections
436+
<Tooltip
437+
>Percentual duration of individual compilation sections. This is a
438+
rough estimate that might not necessarily contain all of the
439+
individual parts of the compilation. The sections are calculated
440+
based on the results of self-profile queries and they are measured
441+
based on wall-time.
442+
</Tooltip>
443+
</div>
444+
<div>
445+
<CompileSectionsChart
446+
v-if="
447+
(sectionsDetail?.before ?? null) !== null &&
448+
(sectionsDetail?.after ?? null) !== null
449+
"
450+
:before="sectionsDetail.before"
451+
:after="sectionsDetail.after"
452+
/>
453+
<span v-else-if="sectionsDetail === null">Loading…</span>
454+
<span v-else>Not available</span>
455+
</div>
456+
</div>
457+
</div>
394458
<div class="command">
395459
<div class="title bold">
396460
Local profiling command<Tooltip>

site/frontend/src/pages/compare/compile/table/detail-resolver.ts

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import {GraphKind, Series} from "../../../../graph/data";
22
import {getJson} from "../../../../utils/requests";
3-
import {COMPARE_COMPILE_DETAIL_GRAPHS_DATA_URL} from "../../../../urls";
3+
import {
4+
COMPARE_COMPILE_DETAIL_GRAPHS_DATA_URL,
5+
COMPARE_COMPILE_DETAIL_SECTIONS_DATA_URL,
6+
} from "../../../../urls";
47
import {CachedDataLoader} from "./utils";
58

69
export interface CompileDetailGraphsSelector {
@@ -18,6 +21,30 @@ export interface CompileDetailGraphs {
1821
commits: Array<[number, string]>;
1922
// One Series for each GraphKind in the CompileDetailSelector
2023
graphs: Series[];
24+
sections_before: CompilationSections | null;
25+
sections_after: CompilationSections | null;
26+
}
27+
28+
export interface CompileDetailSectionsSelector {
29+
start: string;
30+
end: string;
31+
benchmark: string;
32+
scenario: string;
33+
profile: string;
34+
}
35+
36+
export interface CompileDetailSections {
37+
before: CompilationSections | null;
38+
after: CompilationSections | null;
39+
}
40+
41+
export interface CompilationSection {
42+
name: string;
43+
value: number;
44+
}
45+
46+
export interface CompilationSections {
47+
sections: CompilationSection[];
2148
}
2249

2350
/**
@@ -36,10 +63,10 @@ export const COMPILE_DETAIL_GRAPHS_RESOLVER: CachedDataLoader<
3663
> = new CachedDataLoader(
3764
(key: CompileDetailGraphsSelector) =>
3865
`${key.benchmark};${key.profile};${key.scenario};${key.start};${key.end};${key.stat};${key.kinds}`,
39-
loadDetail
66+
loadGraphsDetail
4067
);
4168

42-
async function loadDetail(
69+
async function loadGraphsDetail(
4370
selector: CompileDetailGraphsSelector
4471
): Promise<CompileDetailGraphs> {
4572
const params = {
@@ -56,3 +83,29 @@ async function loadDetail(
5683
params
5784
);
5885
}
86+
87+
// The same thing, but for sections
88+
export const COMPILE_DETAIL_SECTIONS_RESOLVER: CachedDataLoader<
89+
CompileDetailSectionsSelector,
90+
CompileDetailSections
91+
> = new CachedDataLoader(
92+
(key: CompileDetailGraphsSelector) =>
93+
`${key.benchmark};${key.profile};${key.scenario};${key.start};${key.end}`,
94+
loadSectionsDetail
95+
);
96+
97+
async function loadSectionsDetail(
98+
selector: CompileDetailSectionsSelector
99+
): Promise<CompileDetailSections> {
100+
const params = {
101+
start: selector.start,
102+
end: selector.end,
103+
benchmark: selector.benchmark,
104+
scenario: selector.scenario,
105+
profile: selector.profile,
106+
};
107+
return await getJson<CompileDetailSections>(
108+
COMPARE_COMPILE_DETAIL_SECTIONS_DATA_URL,
109+
params
110+
);
111+
}

0 commit comments

Comments
 (0)