Skip to content

Add benchmark detail to compile benchmark in compare page #1689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion site/frontend/src/pages/compare/compile/benchmarks.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="tsx">
import {computed, h} from "vue";
import ComparisonsTable from "./comparisons-table.vue";
import ComparisonsTable from "./table/comparisons-table.vue";
import {TestCaseComparison} from "../data";
import {CompareResponse} from "../types";
import {
Expand Down
91 changes: 91 additions & 0 deletions site/frontend/src/pages/compare/compile/table/benchmark-detail.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<script setup lang="ts">
import {
CargoProfileMetadata,
CompileBenchmarkMap,
CompileBenchmarkMetadata,
CompileTestCase,
} from "../common";
import {computed} from "vue";
import Tooltip from "../../tooltip.vue";

const props = defineProps<{
testCase: CompileTestCase;
benchmarkMap: CompileBenchmarkMap;
}>();
const metadata = computed(
(): CompileBenchmarkMetadata =>
props.benchmarkMap[props.testCase.benchmark] ?? null
);
const cargoProfile = computed((): CargoProfileMetadata => {
if (
props.testCase.profile === "opt" &&
metadata?.value.release_profile !== null
) {
return metadata.value.release_profile;
} else if (
props.testCase.profile === "debug" &&
metadata?.value.dev_profile !== null
) {
return metadata?.value.dev_profile;
}
});
</script>
<template>
<table>
<tbody>
<tr>
<td>Benchmark</td>
<td>{{ testCase.benchmark }}</td>
</tr>
<tr>
<td>Profile</td>
<td>{{ testCase.profile }}</td>
</tr>
<tr>
<td>Scenario</td>
<td>{{ testCase.scenario }}</td>
</tr>
<tr>
<td>Category</td>
<td>{{ testCase.category }}</td>
</tr>
<tr v-if="(metadata?.binary ?? null) !== null">
<td>Artifact</td>
<td>{{ metadata.binary ? "binary" : "library" }}</td>
</tr>
<tr v-if="(metadata?.iterations ?? null) !== null">
<td>
Iterations<Tooltip>
How many times is the benchmark executed?
</Tooltip>
</td>
<td>{{ metadata.iterations }}</td>
</tr>
<tr v-if="(cargoProfile?.lto ?? null) !== null">
<td>LTO</td>
<td>{{ cargoProfile.lto }}</td>
</tr>
<tr v-if="(cargoProfile?.debug ?? null) !== null">
<td>Debuginfo</td>
<td>{{ cargoProfile.debug }}</td>
</tr>
<tr v-if="(cargoProfile?.codegen_units ?? null) !== null">
<td>Codegen units</td>
<td>{{ cargoProfile.codegen_units }}</td>
</tr>
</tbody>
</table>
</template>

<style scoped lang="scss">
table {
td {
text-align: left;

&:first-child {
font-weight: bold;
padding-right: 10px;
}
}
}
</style>
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<script setup lang="ts">
import {TestCaseComparison} from "../data";
import Tooltip from "../tooltip.vue";
import {ArtifactDescription} from "../types";
import {percentClass} from "../shared";
import {CompileBenchmarkMap, CompileTestCase} from "./common";
import {TestCaseComparison} from "../../data";
import Tooltip from "../../tooltip.vue";
import {ArtifactDescription} from "../../types";
import {percentClass} from "../../shared";
import {CompileBenchmarkMap, CompileTestCase} from "../common";
import {computed} from "vue";
import {useExpandedStore} from "./expansion";
import BenchmarkDetail from "./benchmark-detail.vue";

const props = defineProps<{
id: string;
Expand Down Expand Up @@ -60,40 +62,13 @@ function prettifyRawNumber(number: number): string {
return number.toLocaleString();
}

function generateBenchmarkTooltip(testCase: CompileTestCase): string {
const metadata = props.benchmarkMap[testCase.benchmark] ?? null;
if (metadata === null) {
return "<No metadata found>";
const columnCount = computed(() => {
const base = 7;
if (props.showRawData) {
return base + 2;
}
let tooltip = `Benchmark: ${testCase.benchmark}
Category: ${metadata.category}
`;
if (metadata.binary !== null) {
tooltip += `Artifact: ${metadata.binary ? "binary" : "library"}\n`;
}
if (metadata.iterations !== null) {
tooltip += `Iterations: ${metadata.iterations}\n`;
}
const addMetadata = ({lto, debug, codegen_units}) => {
if (lto !== null) {
tooltip += `LTO: ${lto}\n`;
}
if (debug !== null) {
tooltip += `Debuginfo: ${debug}\n`;
}
if (codegen_units !== null) {
tooltip += `Codegen units: ${codegen_units}\n`;
}
};
if (testCase.profile === "opt" && metadata.release_profile !== null) {
addMetadata(metadata.release_profile);
} else if (testCase.profile === "debug" && metadata.dev_profile !== null) {
addMetadata(metadata.dev_profile);
}

return tooltip;
}

return base;
});
const unit = computed(() => {
// The DB stored wall-time data in seconds for compile benchmarks, so it is
// hardcoded here
Expand All @@ -103,6 +78,7 @@ const unit = computed(() => {
return null;
}
});
const {toggleExpanded, isExpanded} = useExpandedStore();
</script>

<template>
Expand All @@ -114,11 +90,12 @@ const unit = computed(() => {
<table v-else class="benches compare">
<thead>
<tr>
<th class="toggle"></th>
<th>Benchmark</th>
<th>Profile</th>
<th>Scenario</th>
<th>% Change</th>
<th>
<th class="narrow">
Significance Threshold
<Tooltip>
The minimum % change that is considered significant. The higher
Expand All @@ -132,7 +109,7 @@ const unit = computed(() => {
how the significance threshold is calculated.
</Tooltip>
</th>
<th>
<th class="narrow">
Significance Factor
<Tooltip>
How much a particular result is over the significance threshold. A
Expand All @@ -147,7 +124,10 @@ const unit = computed(() => {
<tbody>
<template v-for="comparison in comparisons">
<tr>
<td :title="generateBenchmarkTooltip(comparison.testCase)">
<td @click="toggleExpanded(comparison.testCase)" class="toggle">
{{ isExpanded(comparison.testCase) ? "▼" : "▶" }}
</td>
<td>
<a
v-bind:href="benchmarkLink(comparison.testCase.benchmark)"
class="silent-link"
Expand Down Expand Up @@ -181,7 +161,7 @@ const unit = computed(() => {
</div>
</div>
</td>
<td>
<td class="narrow">
<div class="numeric-aligned">
<div>
{{
Expand All @@ -192,7 +172,7 @@ const unit = computed(() => {
</div>
</div>
</td>
<td>
<td class="narrow">
<div class="numeric-aligned">
<div>
{{
Expand All @@ -218,6 +198,14 @@ const unit = computed(() => {
</a>
</td>
</tr>
<tr v-if="isExpanded(comparison.testCase)">
<td :colspan="columnCount">
<BenchmarkDetail
:test-case="comparison.testCase"
:benchmark-map="benchmarkMap"
/>
</td>
</tr>
</template>
</tbody>
</table>
Expand All @@ -226,8 +214,9 @@ const unit = computed(() => {

<style scoped lang="scss">
.benches {
width: 100%;
table-layout: auto;
font-size: medium;
table-layout: fixed;

td,
th {
Expand All @@ -249,15 +238,22 @@ const unit = computed(() => {
border-right: dotted 1px;
}

.benches th {
text-align: center;
min-width: 50px;
.benches {
td,
th {
text-align: center;

&.toggle {
padding-right: 5px;
cursor: pointer;
}
&.narrow {
max-width: 100px;
}
}
}

.benches td {
text-align: center;
width: 25%;

& > .numeric-aligned {
display: flex;
flex-direction: column;
Expand Down
25 changes: 25 additions & 0 deletions site/frontend/src/pages/compare/compile/table/expansion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {ref} from "vue";
import {CompileTestCase} from "../common";

export function useExpandedStore() {
const expanded = ref(new Set());

function isExpanded(testCase: CompileTestCase) {
return expanded.value.has(testCaseKey(testCase));
}

function toggleExpanded(testCase: CompileTestCase) {
const key = testCaseKey(testCase);
if (isExpanded(testCase)) {
expanded.value.delete(key);
} else {
expanded.value.add(key);
}
}

return {toggleExpanded, isExpanded};
}

function testCaseKey(testCase: CompileTestCase): string {
return `${testCase.benchmark};${testCase.profile};${testCase.scenario};${testCase.category}`;
}