<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes" /> <style> html { font-family: BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif; -webkit-font-smoothing: antialiased; background-color: #fff; font-size: 16px; } body { color: #4a4a4a; margin: 8px; font-size: 1em; font-weight: 400; } header { margin-bottom: 8px; display: flex; flex-direction: column; } main { width: 100%; display: flex; flex-direction: column; } a { color: #3273dc; cursor: pointer; text-decoration: none; } a:hover { color: #000; } button { color: #fff; background-color: #3298dc; border-color: transparent; cursor: pointer; text-align: center; } button:hover { background-color: #2793da; flex: none; } .spacer { flex: auto; } .small { font-size: 0.75rem; } footer { margin-top: 16px; display: flex; align-items: center; } .header-label { margin-right: 4px; } .benchmark-set { margin: 8px 0; width: 100%; display: flex; flex-direction: column; } .benchmark-title { font-size: 3rem; font-weight: 600; word-break: break-word; text-align: center; } .benchmark-graphs { display: flex; flex-direction: row; justify-content: space-around; align-items: center; flex-wrap: wrap; width: 100%; } .benchmark-chart { max-width: 1000px; } </style> <title>Benchmarks</title> </head> <body> <header id="header"> <div class="header-item"> <strong class="header-label">Last Update:</strong> <span id="last-update"></span> </div> <div class="header-item"> <strong class="header-label">Repository:</strong> <a id="repository-link" rel="noopener"></a> </div> </header> <main id="main"></main> <footer> <button id="dl-button">Download data as JSON</button> <div class="spacer"></div> <div class="small">Powered by <a rel="noopener" href="https://github.com/marketplace/actions/continuous-benchmark">github-action-benchmark</a></div> </footer> <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.2/dist/Chart.min.js"></script> <script src="data.js"></script> <script id="main-script"> 'use strict'; (function() { // Colors from https://github.com/github/linguist/blob/master/lib/linguist/languages.yml const toolColors = { cargo: '#dea584', go: '#00add8', benchmarkjs: '#f1e05a', benchmarkluau: '#000080', pytest: '#3572a5', googlecpp: '#f34b7d', catch2: '#f34b7d', julia: '#a270ba', jmh: '#b07219', benchmarkdotnet: '#178600', customBiggerIsBetter: '#38ff38', customSmallerIsBetter: '#ff3838', _: '#333333' }; function init() { function collectBenchesPerTestCase(entries) { const map = new Map(); for (const entry of entries) { const {commit, date, tool, benches} = entry; for (const bench of benches) { const result = { commit, date, tool, bench }; const arr = map.get(bench.name); if (arr === undefined) { map.set(bench.name, [result]); } else { arr.push(result); } } } return map; } const data = window.BENCHMARK_DATA; // Render header document.getElementById('last-update').textContent = new Date(data.lastUpdate).toString(); const repoLink = document.getElementById('repository-link'); repoLink.href = data.repoUrl; repoLink.textContent = data.repoUrl; // Render footer document.getElementById('dl-button').onclick = () => { const dataUrl = 'data:,' + JSON.stringify(data, null, 2); const a = document.createElement('a'); a.href = dataUrl; a.download = 'benchmark_data.json'; a.click(); }; // Prepare data points for charts return Object.keys(data.entries).map(name => ({ name, dataSet: collectBenchesPerTestCase(data.entries[name]), })); } function renderAllChars(dataSets) { function renderGraph(parent, name, dataset) { const canvas = document.createElement('canvas'); canvas.className = 'benchmark-chart'; parent.appendChild(canvas); const color = toolColors[dataset.length > 0 ? dataset[0].tool : '_']; const data = { labels: dataset.map(d => d.commit.id.slice(0, 7)), datasets: [ { label: name, data: dataset.map(d => d.bench.value), borderColor: color, backgroundColor: color + '60', // Add alpha for #rrggbbaa } ], }; const options = { scales: { xAxes: [ { scaleLabel: { display: true, labelString: 'commit', }, } ], yAxes: [ { scaleLabel: { display: true, labelString: dataset.length > 0 ? dataset[0].bench.unit : '', }, ticks: { beginAtZero: true, } } ], }, tooltips: { callbacks: { afterTitle: items => { const {index} = items[0]; const data = dataset[index]; return '\n' + data.commit.message + '\n\n' + data.commit.timestamp + ' committed by @' + data.commit.committer.username + '\n'; }, label: item => { let label = item.value; const { range, unit } = dataset[item.index].bench; label += ' ' + unit; if (range) { label += ' (' + range + ')'; } return label; }, afterLabel: item => { const { extra } = dataset[item.index].bench; return extra ? '\n' + extra : ''; } } }, onClick: (_mouseEvent, activeElems) => { if (activeElems.length === 0) { return; } // XXX: Undocumented. How can we know the index? const index = activeElems[0]._index; const url = dataset[index].commit.url; window.open(url, '_blank'); }, }; new Chart(canvas, { type: 'line', data, options, }); } function renderBenchSet(name, benchSet, main) { const setElem = document.createElement('div'); setElem.className = 'benchmark-set'; main.appendChild(setElem); const nameElem = document.createElement('h1'); nameElem.className = 'benchmark-title'; nameElem.textContent = name; setElem.appendChild(nameElem); const graphsElem = document.createElement('div'); graphsElem.className = 'benchmark-graphs'; setElem.appendChild(graphsElem); for (const [benchName, benches] of benchSet.entries()) { renderGraph(graphsElem, benchName, benches) } } const main = document.getElementById('main'); for (const {name, dataSet} of dataSets) { renderBenchSet(name, dataSet, main); } } renderAllChars(init()); // Start })(); </script> </body> </html>