Skip to content

Commit e6610ac

Browse files
authored
Merge pull request #202 from kayjan/benchmark-gh-pages
Add: index.html for benchmark results
2 parents 3d5fa44 + eee4182 commit e6610ac

File tree

1 file changed

+279
-0
lines changed

1 file changed

+279
-0
lines changed

docs/dev/bench/index.html

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes" />
6+
<style>
7+
html {
8+
font-family: BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
9+
-webkit-font-smoothing: antialiased;
10+
background-color: #fff;
11+
font-size: 16px;
12+
}
13+
body {
14+
color: #4a4a4a;
15+
margin: 8px;
16+
font-size: 1em;
17+
font-weight: 400;
18+
}
19+
header {
20+
margin-bottom: 8px;
21+
display: flex;
22+
flex-direction: column;
23+
}
24+
main {
25+
width: 100%;
26+
display: flex;
27+
flex-direction: column;
28+
}
29+
a {
30+
color: #3273dc;
31+
cursor: pointer;
32+
text-decoration: none;
33+
}
34+
a:hover {
35+
color: #000;
36+
}
37+
button {
38+
color: #fff;
39+
background-color: #3298dc;
40+
border-color: transparent;
41+
cursor: pointer;
42+
text-align: center;
43+
}
44+
button:hover {
45+
background-color: #2793da;
46+
flex: none;
47+
}
48+
.spacer {
49+
flex: auto;
50+
}
51+
.small {
52+
font-size: 0.75rem;
53+
}
54+
footer {
55+
margin-top: 16px;
56+
display: flex;
57+
align-items: center;
58+
}
59+
.header-label {
60+
margin-right: 4px;
61+
}
62+
.benchmark-set {
63+
margin: 8px 0;
64+
width: 100%;
65+
display: flex;
66+
flex-direction: column;
67+
}
68+
.benchmark-title {
69+
font-size: 3rem;
70+
font-weight: 600;
71+
word-break: break-word;
72+
text-align: center;
73+
}
74+
.benchmark-graphs {
75+
display: flex;
76+
flex-direction: row;
77+
justify-content: space-around;
78+
align-items: center;
79+
flex-wrap: wrap;
80+
width: 100%;
81+
}
82+
.benchmark-chart {
83+
max-width: 1000px;
84+
}
85+
</style>
86+
<title>Benchmarks</title>
87+
</head>
88+
89+
<body>
90+
<header id="header">
91+
<div class="header-item">
92+
<strong class="header-label">Last Update:</strong>
93+
<span id="last-update"></span>
94+
</div>
95+
<div class="header-item">
96+
<strong class="header-label">Repository:</strong>
97+
<a id="repository-link" rel="noopener"></a>
98+
</div>
99+
</header>
100+
<main id="main"></main>
101+
<footer>
102+
<button id="dl-button">Download data as JSON</button>
103+
<div class="spacer"></div>
104+
<div class="small">Powered by <a rel="noopener" href="https://github.com/marketplace/actions/continuous-benchmark">github-action-benchmark</a></div>
105+
</footer>
106+
107+
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.2/dist/Chart.min.js"></script>
108+
<script src="data.js"></script>
109+
<script id="main-script">
110+
'use strict';
111+
(function() {
112+
// Colors from https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
113+
const toolColors = {
114+
cargo: '#dea584',
115+
go: '#00add8',
116+
benchmarkjs: '#f1e05a',
117+
pytest: '#3572a5',
118+
googlecpp: '#f34b7d',
119+
catch2: '#f34b7d',
120+
julia: '#a270ba',
121+
benchmarkdotnet: '#178600',
122+
customBiggerIsBetter: '#38ff38',
123+
customSmallerIsBetter: '#ff3838',
124+
_: '#333333'
125+
};
126+
127+
function init() {
128+
function collectBenchesPerTestCase(entries) {
129+
const map = new Map();
130+
for (const entry of entries) {
131+
const {commit, date, tool, benches} = entry;
132+
for (const bench of benches) {
133+
const result = { commit, date, tool, bench };
134+
const arr = map.get(bench.name);
135+
if (arr === undefined) {
136+
map.set(bench.name, [result]);
137+
} else {
138+
arr.push(result);
139+
}
140+
}
141+
}
142+
return map;
143+
}
144+
145+
const data = window.BENCHMARK_DATA;
146+
147+
// Render header
148+
document.getElementById('last-update').textContent = new Date(data.lastUpdate).toString();
149+
const repoLink = document.getElementById('repository-link');
150+
repoLink.href = data.repoUrl;
151+
repoLink.textContent = data.repoUrl;
152+
153+
// Render footer
154+
document.getElementById('dl-button').onclick = () => {
155+
const dataUrl = 'data:,' + JSON.stringify(data, null, 2);
156+
const a = document.createElement('a');
157+
a.href = dataUrl;
158+
a.download = 'benchmark_data.json';
159+
a.click();
160+
};
161+
162+
// Prepare data points for charts
163+
return Object.keys(data.entries).map(name => ({
164+
name,
165+
dataSet: collectBenchesPerTestCase(data.entries[name]),
166+
}));
167+
}
168+
169+
function renderAllChars(dataSets) {
170+
171+
function renderGraph(parent, name, dataset) {
172+
const canvas = document.createElement('canvas');
173+
canvas.className = 'benchmark-chart';
174+
parent.appendChild(canvas);
175+
176+
const color = toolColors[dataset.length > 0 ? dataset[0].tool : '_'];
177+
const data = {
178+
labels: dataset.map(d => d.commit.id.slice(0, 7)),
179+
datasets: [
180+
{
181+
label: name,
182+
data: dataset.map(d => d.bench.value),
183+
borderColor: color,
184+
backgroundColor: color + '60', // Add alpha for #rrggbbaa
185+
}
186+
],
187+
};
188+
const options = {
189+
scales: {
190+
xAxes: [
191+
{
192+
scaleLabel: {
193+
display: true,
194+
labelString: 'commit',
195+
},
196+
}
197+
],
198+
yAxes: [
199+
{
200+
scaleLabel: {
201+
display: true,
202+
labelString: dataset.length > 0 ? dataset[0].bench.unit : '',
203+
},
204+
ticks: {
205+
beginAtZero: true,
206+
}
207+
}
208+
],
209+
},
210+
tooltips: {
211+
callbacks: {
212+
afterTitle: items => {
213+
const {index} = items[0];
214+
const data = dataset[index];
215+
return '\n' + data.commit.message + '\n\n' + data.commit.timestamp + ' committed by @' + data.commit.committer.username + '\n';
216+
},
217+
label: item => {
218+
let label = item.value;
219+
const { range, unit } = dataset[item.index].bench;
220+
label += ' ' + unit;
221+
if (range) {
222+
label += ' (' + range + ')';
223+
}
224+
return label;
225+
},
226+
afterLabel: item => {
227+
const { extra } = dataset[item.index].bench;
228+
return extra ? '\n' + extra : '';
229+
}
230+
}
231+
},
232+
onClick: (_mouseEvent, activeElems) => {
233+
if (activeElems.length === 0) {
234+
return;
235+
}
236+
// XXX: Undocumented. How can we know the index?
237+
const index = activeElems[0]._index;
238+
const url = dataset[index].commit.url;
239+
window.open(url, '_blank');
240+
},
241+
};
242+
243+
new Chart(canvas, {
244+
type: 'line',
245+
data,
246+
options,
247+
});
248+
}
249+
250+
function renderBenchSet(name, benchSet, main) {
251+
const setElem = document.createElement('div');
252+
setElem.className = 'benchmark-set';
253+
main.appendChild(setElem);
254+
255+
const nameElem = document.createElement('h1');
256+
nameElem.className = 'benchmark-title';
257+
nameElem.textContent = name;
258+
setElem.appendChild(nameElem);
259+
260+
const graphsElem = document.createElement('div');
261+
graphsElem.className = 'benchmark-graphs';
262+
setElem.appendChild(graphsElem);
263+
264+
for (const [benchName, benches] of benchSet.entries()) {
265+
renderGraph(graphsElem, benchName, benches)
266+
}
267+
}
268+
269+
const main = document.getElementById('main');
270+
for (const {name, dataSet} of dataSets) {
271+
renderBenchSet(name, dataSet, main);
272+
}
273+
}
274+
275+
renderAllChars(init()); // Start
276+
})();
277+
</script>
278+
</body>
279+
</html>

0 commit comments

Comments
 (0)