blob: fd2c6483a7061ed76f11bbf751cff625917e1682 [file] [log] [blame]
<!--
Copyright 2022 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Go Performance Dashboard</title>
<link rel="icon" href="https://go.dev/favicon.ico"/>
<link rel="stylesheet" href="./static/style.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/d3js/7.4.2/d3.min.js"></script>
<script src="./third_party/bandchart/bandchart.js"></script>
</head>
<body class="Dashboard">
<header class="Dashboard-topbar">
<h1>
<a href="https://farmer.golang.org/">Go Build Coordinator</a>
</h1>
<nav>
<ul>
<li><a href="https://build.golang.org/">Build Dashboard</a></li>
<li><a href="/dashboard">Performance Dashboard</a></li>
<li><a href="https://farmer.golang.org/builders">Builders</a></li>
</ul>
</nav>
</header>
<nav class="Dashboard-controls">
<form autocomplete="off" action="./">
<ul>
<li>
<div class="Dashboard-search">
<input id="benchmark-input" type="text" name="benchmark" placeholder="Type benchmark name..." />
</div>
<input type="submit" />
</li>
<li><a href="?benchmark=all">All benchmarks</a></li>
<span class="left-separator"></span>
<li>
Duration (days):
<div class="Dashboard-duration">
<input id="days-input" type="number" name="days" value="30" />
</div>
End (UTC): <input id="end-input" type="datetime-local" name="end" />
<input type="submit">
</li>
</ul>
</form>
</nav>
<div class="Dashboard-documentation">
<p>
Each graph displays benchmark results relative to its baseline
commit, which is the latest stable release (e.g., 1.18.3) at
the time of testing. The 95% confidence interval is displayed
in light gray. On hover, the graph displays the benchmarked
commit at that point (click to view full commit).
</p>
<p>
Note that some commits are not tested, so there could be
multiple commits (not shown) between two points on the graph.
See the <code>linux-amd64-perf</code> column on the
<a href="https://build.golang.org/?repo=golang.org%2fx%2fbenchmarks">x/benchmarks build dashboard</a>
for tested ("ok") / untested (empty) commits.
</p>
</div>
<div id="dashboard">
<h2 class="Dashboard-title" id="loading">Loading...</h2>
</div>
<script>
function removeLoadingMessage() {
let loading = document.getElementById("loading");
loading.parentNode.removeChild(loading);
}
function addContent(benchmarks) {
let dashboard = document.getElementById("dashboard");
removeLoadingMessage();
let prevName = "";
let grid = null;
for (const b in benchmarks) {
const bench = benchmarks[b];
if (bench.Name != prevName) {
prevName = bench.Name;
let link = document.createElement("a");
link.href = "?benchmark=" + bench.Name;
link.innerHTML = bench.Name;
let title = document.createElement("h2");
title.classList.add("Dashboard-title");
title.appendChild(link);
dashboard.appendChild(title);
grid = document.createElement("grid");
grid.classList.add("Dashboard-grid");
dashboard.appendChild(grid);
}
let item = document.createElement("div");
item.classList.add("Dashboard-grid-item");
item.appendChild(BandChart(bench.Values, {
unit: bench.Unit,
}));
grid.appendChild(item);
}
}
function failure(name, response) {
let dashboard = document.getElementById("dashboard");
removeLoadingMessage();
let title = document.createElement("h2");
title.classList.add("Dashboard-title");
title.innerHTML = "Benchmark \"" + name + "\" not found.";
dashboard.appendChild(title);
let message = document.createElement("p");
message.classList.add("Dashboard-documentation");
response.text().then(function(error) {
message.innerHTML = error;
});
dashboard.appendChild(message);
}
// Fill search boxes from query params.
function prefillSearch() {
let params = new URLSearchParams(window.location.search);
let benchmark = params.get('benchmark');
if (benchmark) {
let input = document.getElementById('benchmark-input');
input.value = benchmark;
}
let days = params.get('days');
if (days) {
let input = document.getElementById('days-input');
input.value = days;
}
let end = params.get('end');
let input = document.getElementById('end-input');
if (end) {
input.value = end;
} else {
// Default to now.
let now = new Date();
// toISOString always uses UTC, then we just chop off the end
// of string to get the datetime-local format of
// 2000-12-31T15:00.
//
// Yes, this is really the suggested approach...
input.value = now.toISOString().slice(0, 16);
}
}
prefillSearch()
// Fetch content.
let benchmark = (new URLSearchParams(window.location.search)).get('benchmark');
let dataURL = './data.json' + window.location.search; // Pass through all URL params.
fetch(dataURL)
.then(response => {
if (!response.ok) {
failure(benchmark, response);
throw new Error("Data fetch failed");
}
return response.json();
})
.then(function(benchmarks) {
// Convert CommitDate to a proper date.
benchmarks.forEach(function(b) {
b.Values.forEach(function(v) {
v.CommitDate = new Date(v.CommitDate);
});
});
addContent(benchmarks);
});
</script>
</body>
</html>