This is an automated email from the ASF dual-hosted git repository.
github-actions[bot] pushed a commit to branch gh-pages
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/gh-pages by this push:
new c29871914e Update compiler performance dashboard page
c29871914e is described below
commit c29871914e0139620f52f82f8503cb8c09814691
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu May 14 21:49:41 2026 +0000
Update compiler performance dashboard page
---
dev/bench/perf/compiler/index.html | 471 +++++++++++++++----------------------
1 file changed, 192 insertions(+), 279 deletions(-)
diff --git a/dev/bench/perf/compiler/index.html
b/dev/bench/perf/compiler/index.html
index 6c887805e8..8aec88ef61 100644
--- a/dev/bench/perf/compiler/index.html
+++ b/dev/bench/perf/compiler/index.html
@@ -1,281 +1,194 @@
<!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/[email protected]/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>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<title>Groovy Compiler Performance Dashboard</title>
+<style>
+ :root { color-scheme: light; }
+ body {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif;
+ margin: 2em auto;
+ max-width: 1200px;
+ padding: 0 1em;
+ color: #222;
+ background: #fff;
+ }
+ h1 { font-weight: 500; margin-bottom: 0.25em; }
+ .intro { color: #444; line-height: 1.45; margin-bottom: 1.5em; max-width:
70ch; }
+ .chart-wrap { position: relative; height: 480px; margin-bottom: 1.5em; }
+ .meta { color: #666; font-size: 0.9em; margin-top: 1em; line-height: 1.5; }
+ .meta a { color: #4A8CC2; text-decoration: none; }
+ .meta a:hover { text-decoration: underline; }
+ code { background: #f5f5f7; padding: 0.05em 0.3em; border-radius: 3px;
font-size: 0.92em; }
+ .empty { color: #888; font-style: italic; }
+</style>
+</head>
+<body>
+<h1>Groovy compiler performance (normalised against current)</h1>
+<p class="intro">
+ Each daily run compiles a fixed set of Groovy source files using
<code>current</code>
+ (master) and the latest releases of Groovy 3.x, 4.x and 5.x. Every series is
divided by
+ the <code>current</code> measurement from the same run, so <code>current =
1.0</code> by
+ construction. Values below 1 mean that version compiles faster than current;
values above
+ 1 mean it compiles slower. The trends show how current drifts relative to
the released lines.
+</p>
+
+<div class="chart-wrap"><canvas id="ratioChart"></canvas></div>
+
+<div class="meta">
+ <div id="lastUpdate"></div>
+ <div id="latest"></div>
+ <div>
+ Raw data: <a href="data.js">data.js</a> ·
+ Generated by <a
href="https://github.com/benchmark-action/github-action-benchmark">github-action-benchmark</a>
·
+ <a href="../../../../">Apache Groovy benchmark home</a>
+ </div>
+</div>
+
+<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
+<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
+<script src="data.js"></script>
+<script>
+(function () {
+ const SERIES = [
+ { name: 'compile@current', label: 'current (master)', color: '#1F77B4' },
+ { name: 'compile@groovy-5', label: 'Groovy 5.x', color: '#2CA02C' },
+ { name: 'compile@groovy-4', label: 'Groovy 4.x', color: '#FF7F0E' },
+ { name: 'compile@groovy-3', label: 'Groovy 3.x', color: '#D62728' },
+ ];
+
+ const data = window.BENCHMARK_DATA || {};
+ const suites = data.entries || {};
+ const suiteName = Object.keys(suites)[0];
+ if (!suiteName) {
+ document.querySelector('.chart-wrap').innerHTML =
+ '<p class="empty">No benchmark data yet — waiting for the first
<code>perf-daily</code> run.</p>';
+ return;
+ }
+ const runs = suites[suiteName] || [];
+
+ const datasets = SERIES.map(s => ({
+ label: s.label,
+ borderColor: s.color,
+ backgroundColor: s.color,
+ pointRadius: 2,
+ pointHoverRadius: 5,
+ borderWidth: 2,
+ tension: 0.15,
+ spanGaps: true,
+ data: [],
+ }));
+
+ const latestVersions = {};
+ for (const run of runs) {
+ const byName = {};
+ for (const b of (run.benches || [])) byName[b.name] = b;
+ const current = byName['compile@current'];
+ if (!current || !current.value) continue;
+ const x = new Date(run.date || (run.commit && run.commit.timestamp) || 0);
+ SERIES.forEach((s, idx) => {
+ const b = byName[s.name];
+ if (!b || !b.value) return;
+ if (b.extra) latestVersions[s.name] = b.extra;
+ datasets[idx].data.push({
+ x,
+ y: b.value / current.value,
+ absMs: b.value,
+ range: b.range || '',
+ commit: (run.commit && run.commit.id) ? run.commit.id.slice(0, 7) : '',
+ commitUrl: run.commit && run.commit.url,
+ version: b.extra || '',
+ });
+ });
+ }
+
+ const baselineLine = {
+ id: 'baselineLine',
+ afterDatasetsDraw(chart) {
+ const { ctx, chartArea: { left, right }, scales: { y } } = chart;
+ const yPx = y.getPixelForValue(1);
+ ctx.save();
+ ctx.strokeStyle = 'rgba(0,0,0,0.35)';
+ ctx.setLineDash([4, 4]);
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+ ctx.moveTo(left, yPx);
+ ctx.lineTo(right, yPx);
+ ctx.stroke();
+ ctx.restore();
+ }
+ };
+
+ const ctx = document.getElementById('ratioChart').getContext('2d');
+ new Chart(ctx, {
+ type: 'line',
+ data: { datasets },
+ plugins: [baselineLine],
+ options: {
+ responsive: true,
+ maintainAspectRatio: false,
+ interaction: { mode: 'index', intersect: false },
+ scales: {
+ x: {
+ type: 'time',
+ time: { unit: 'day', tooltipFormat: 'yyyy-MM-dd' },
+ title: { display: true, text: 'Run date' },
+ },
+ y: {
+ title: { display: true, text: 'compile time / current (ratio)' },
+ grid: { color: 'rgba(0,0,0,0.06)' },
+ },
+ },
+ plugins: {
+ legend: { position: 'top' },
+ tooltip: {
+ callbacks: {
+ title(items) {
+ const r = items[0] && items[0].raw;
+ const d = new Date(items[0].parsed.x).toISOString().slice(0, 10);
+ return r && r.commit ? r.commit + ' ' + d : d;
+ },
+ label(item) {
+ const r = item.raw;
+ const ratio = item.parsed.y.toFixed(3);
+ const abs = r.absMs ? r.absMs.toFixed(1) + ' ms' : '';
+ const rng = r.range ? ' ' + r.range : '';
+ const ver = r.version ? ' [' + r.version + ']' : '';
+ return item.dataset.label + ': ' + ratio + ' x (' + abs + rng +
')' + ver;
+ },
+ },
+ },
+ },
+ },
+ });
+
+ if (data.lastUpdate) {
+ document.getElementById('lastUpdate').textContent =
+ 'Last update: ' + new Date(data.lastUpdate).toISOString().replace('T', '
').slice(0, 19) + ' UTC';
+ }
+ const pieces = SERIES
+ .filter(s => latestVersions[s.name])
+ .map(s => s.label + ': ' + latestVersions[s.name]);
+ if (pieces.length) {
+ document.getElementById('latest').textContent = 'Latest versions in chart:
' + pieces.join(' | ');
+ }
+})();
+</script>
+</body>
</html>