<!--
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>
	<script src="./static/range.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-benchmark">
					<input id="benchmark-input" type="text" name="benchmark" placeholder="Type benchmark name..." />
				</div>
				<div class="Dashboard-search-unit">
					<input id="unit-input" type="text" name="unit" placeholder="Unit (optional)" />
				</div>
				<input type="submit" />
			</li>
			<li><a href="?benchmark=all">All benchmarks</a></li>
			<li><a href="?benchmark=regressions">Regressions first</a></li>
			<span class="left-separator"></span>
			<li>
				Repository:
				<select id="repository-select" name="repository">
					<option>go</option>
					<option>tools</option>
				</select>
				Branch:
				<select id="branch-select" name="branch">
					<option>master</option>
					<option>release-branch.go1.17</option>
					<option>release-branch.go1.18</option>
					<option>release-branch.go1.19</option>
					<option>release-branch.go1.20</option>
				</select>
				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>
	<p>
		The 'branch' selection above is the Go branch that benchmarking
		ran against on <a href=https://build.golang.org>the build dashboard</a>,
		not the subrepo branch.
	</p>
	<p>
		Using the 'unit' search box above leads to a page that shows much
		more detail about each individual point in the selected time range.
		Another way of reaching this page is to click the unit name that acts
		as each graph's title, i.e. "sec/op".
	</p>
</div>

<grid id="dashboard">
	<grid id="loading" class="Dashboard-section Dashboard-section-expand">
		<h2 class="Dashboard-title" id="loading">Loading...</h2>
	</grid>
</grid>

<script>
// minViewPercentDelta represents the minimum range we're willing to
// let the Y axis have for charts and X axis for ranges in the per-unit
// view. In both cases the unit of this value is a delta percent, hence
// the name.
//
// This constant exists because allowing the axis' range to be arbitrarily
// small produces results that are really noisy visually, even though they
// represent virtually no change. For instance, a relatively low-noise
// series of benchmark results, with a min delta of -0.05% and +0.05%
// might appear really noisy if we "zoom" in too far, when in actuality
// the amount of noise is incredibly low.
const minViewDeltaPercent = 0.025;

function removeLoadingMessage() {
	let loading = document.getElementById("loading");
	loading.parentNode.removeChild(loading);
}

function addCharts(benchmarks, repository) {
	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 section = document.createElement("grid");
			section.classList.add("Dashboard-section");
			dashboard.appendChild(section);

			let link = document.createElement("a");
			link.href = "?benchmark=" + bench.Name;
			link.textContent = bench.Name;

			let title = document.createElement("h2");
			title.classList.add("Dashboard-title");
			title.appendChild(link);
			section.appendChild(title);

			grid = document.createElement("grid");
			grid.classList.add("Dashboard-grid");
			section.appendChild(grid);
		}

		let item = document.createElement("div");
		item.classList.add("Dashboard-grid-item");
		if (bench.Regression) {
			const p = document.createElement("p");
			p.classList.add("Dashboard-regression-description");
			const r = bench.Regression;
			if (r.DeltaIndex >= 0) {
				// Generate some text indicating the regression.
				const rd = bench.Values[r.DeltaIndex];
				const regression = (Math.abs(r.Change)*100).toFixed(2);
				const shortCommit = rd.CommitHash.slice(0, 7);
				let diffText = "regression";
				let isRegression = true;
				if (r.Change < 0) {
					// Note: r.Change already has its sign flipped for HigherIsBetter.
					// Positive always means regression, negative always means improvement.
					diffText = "improvement";
					isRegression = false;
				}
				p.innerHTML = `${regression}% ${diffText}, ${(r.Delta*100).toFixed(2)}%-point change at <a href="?benchmark=${bench.Name}&unit=${bench.Unit}#${commitToId(rd.CommitHash)}">${shortCommit}</a>.`;

				// Add a link to file a bug.
				if (isRegression) {
					const title = `affected/package: ${regression}% regression in ${bench.Name} ${bench.Unit} at ${shortCommit}`;
					const body = `Discovered a regression in ${bench.Unit} of ${regression}% for benchmark ${bench.Name} at ${shortCommit}.\n\n<ADD MORE DETAILS>.`
					let query = `?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}&labels=Performance`;
					p.innerHTML += ` <a href="https://github.com/golang/go/issues/new${query}">File an issue</a>.`;
				} else {
					// Include a grinning emoji if it's an improvement.
					p.innerHTML += ` <span style="font-style: normal;">&#128513;</span>`;
				}
			} else {
				p.textContext = `Not ranked because ${r.IgnoredBecause}.`;
			}
			item.appendChild(p);
		}
		item.appendChild(BandChart(bench.Values, {
			benchmark: bench.Name,
			unit: bench.Unit,
			repository: repository,
			minViewDeltaPercent: minViewDeltaPercent,
			higherIsBetter: bench.HigherIsBetter,
		}));
		grid.appendChild(item);
	}
}

function commitToId(commitHash) {
	return "commit" + commitHash;
}

function idToCommit(id) {
	if (id && id.startsWith("commit")) {
		return id.slice(6);
	}
	return null;
}

function addTable(bench, unit, repository) {
	let commitSelected = idToCommit(window.location.hash.slice(1));
	let dashboard = document.getElementById("dashboard");

	removeLoadingMessage();

	let section = document.createElement("grid");
	section.classList.add("Dashboard-section");
	section.classList.add("Dashboard-section-expand");
	dashboard.appendChild(section);

	let link = document.createElement("a");
	link.href = "?benchmark=" + bench.Name + "&unit=" + unit;
	link.textContent = bench.Name + " (" + unit + ")";

	let title = document.createElement("h2");
	title.classList.add("Dashboard-title");
	title.appendChild(link);
	section.appendChild(title);

	const table = document.createElement("table");
	table.classList.add("Dashboard-table");
	section.appendChild(table);

	const createCell = function(text, header) {
		let elemType = "td";
		if (header) {
			elemType = "th";
		}
		const elem = document.createElement(elemType);
		elem.textContent = text;
		return elem;
	}

	// Create the header.
	const header = document.createElement("tr");
	header.appendChild(createCell("Date", true));
	header.appendChild(createCell("Commit", true));
	header.appendChild(createCell("Delta", true));
	table.appendChild(header);

	// Find the min and max.
	let min = bench.Values[0].Low;
	let max = bench.Values[0].High;
	for (let i = 1; i < bench.Values.length; i++) {
		if (bench.Values[i].Low < min) {
			min = bench.Values[i].Low;
		}
		if (bench.Values[i].High > max) {
			max = bench.Values[i].High;
		}
	}

	// Clamp for presentation.
	if (min < 0 && min > -minViewDeltaPercent) {
		min = -minViewDeltaPercent
	}
	if (max > 0 && max < minViewDeltaPercent) {
		max = minViewDeltaPercent
	}
	if (max-min < 2*minViewDeltaPercent) {
		const amt = (2*minViewDeltaPercent-(max-min))/2;
		max += amt;
		min -= amt;
	}

	// Iterate backwards, showing the most recent first.
	for (let i = bench.Values.length-1; i >= 0; i--) {
		const v = bench.Values[i];

		// Create a row per value.
		const row = document.createElement("tr");
		if (commitSelected && commitSelected === v.CommitHash) {
			row.classList.add("selected");
		}

		// Commit date.
		row.appendChild(createCell(Intl.DateTimeFormat([], {
			dateStyle: "long",
			timeStyle: "short",
		}).format(v.CommitDate), false));

		// Commit hash.
		const commitHash = createCell("", false);
		const commitLink = document.createElement("a");
		commitLink.href = "https://go.googlesource.com/" + repository + "/+show/" + v.CommitHash;
		commitLink.id = commitToId(v.CommitHash);
		commitLink.textContent = v.CommitHash.slice(0, 7);
		commitHash.appendChild(commitLink);
		commitHash.classList.add("Dashboard-table-commit")
		row.appendChild(commitHash);

		// Range visualization.
		const range = createCell("", false);
		range.appendChild(Range(v.Low, v.Center, v.High, min, max, 640, 48, bench.Unit, bench.HigherIsBetter));
		range.classList.add("Dashboard-table-range")
		row.appendChild(range);

		table.appendChild(row);
	}

	if (commitSelected) {
		// Now that we've generated anchors for every commit, let's scroll to the
		// right one. The browser won't do this automatically because the anchors
		// don't exist when the page is loaded.
		const anchor = document.querySelector("#" + commitToId(commitSelected));
		window.scrollTo({
			top: anchor.getBoundingClientRect().top + window.pageYOffset - 20,
		})
	}
}

function failure(name, response) {
	let dashboard = document.getElementById("dashboard");

	removeLoadingMessage();

	let title = document.createElement("h2");
	title.classList.add("Dashboard-title");
	title.textContent = "Benchmark \"" + name + "\" not found.";
	dashboard.appendChild(title);

	let message = document.createElement("p");
	message.classList.add("Dashboard-documentation");
	response.text().then(function(error) {
		message.textContent = 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 unit = params.get('unit');
	if (unit) {
		let input = document.getElementById('unit-input');
		input.value = unit;
	}

	let repository = params.get('repository');
	if (repository) {
		let select = document.getElementById('repository-select');
		select.value = repository;
	}

	let branch = params.get('branch');
	if (branch) {
		let select = document.getElementById('branch-select');
		select.value = branch;
	}

	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()

// Grab the repository so we can plumb it into UI elements.
// prefillSearch set this up for us just now.
const repository = document.getElementById('repository-select').value;

// Fetch content.
let benchmark = (new URLSearchParams(window.location.search)).get('benchmark');
let unit = (new URLSearchParams(window.location.search)).get('unit');
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);
			});
		});

		// If we have an explicit unit, then there should be just one result.
		if (unit) {
			if (benchmarks.length !== 1) {
				failure(benchmark, "got more that one benchmark when a unit was specified");
				throw new Error("Data fetch failed");
			}
			addTable(benchmarks[0], unit, repository);
		} else {
			addCharts(benchmarks, repository);
		}
	});
</script>

</body>
</html>
