add Java JMH Benchmark (jmh) benchmark result for 95a6fcfebec4e71dbd9f29fb86360f65b6d170db
diff --git a/dev/bench/data.js b/dev/bench/data.js new file mode 100644 index 0000000..a801cb5 --- /dev/null +++ b/dev/bench/data.js
@@ -0,0 +1,90 @@ +window.BENCHMARK_DATA = { + "lastUpdate": 1789620432959, + "repoUrl": "https://github.com/jakartaee/jsonp-api", + "entries": { + "Java JMH Benchmark": [ + { + "commit": { + "author": { + "name": "Mark Swatosh", + "username": "mswatosh", + "email": "mark.swatosh@gmail.com" + }, + "committer": { + "name": "GitHub", + "username": "web-flow", + "email": "noreply@github.com" + }, + "id": "95a6fcfebec4e71dbd9f29fb86360f65b6d170db", + "message": "Merge pull request #419 from mswatosh/2.2-updates\n\nModernization updates", + "timestamp": "2026-09-16T14:05:46Z", + "url": "https://github.com/jakartaee/jsonp-api/commit/95a6fcfebec4e71dbd9f29fb86360f65b6d170db" + }, + "date": 1789620432194, + "tool": "jmh", + "benches": [ + { + "name": "jakarta.json.jmh.FactoryBenchmark.createArrayBuilder_viaFactory", + "value": 474020.44722800486, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + }, + { + "name": "jakarta.json.jmh.FactoryBenchmark.createArrayBuilder_viaJson", + "value": 70.5623061574805, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + }, + { + "name": "jakarta.json.jmh.FactoryBenchmark.createArrayBuilder_viaProvider", + "value": 472428.9777620599, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + }, + { + "name": "jakarta.json.jmh.FactoryBenchmark.createObjectBuilder_viaFactory", + "value": 478191.12767356884, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + }, + { + "name": "jakarta.json.jmh.FactoryBenchmark.createObjectBuilder_viaJson", + "value": 70.60008103630392, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + }, + { + "name": "jakarta.json.jmh.FactoryBenchmark.createObjectBuilder_viaProvider", + "value": 468808.19612871547, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + }, + { + "name": "jakarta.json.jmh.FactoryBenchmark.createValueInt_viaJson", + "value": 70.52208995508097, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + }, + { + "name": "jakarta.json.jmh.FactoryBenchmark.createValueInt_viaProvider", + "value": 470857.4889377388, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + }, + { + "name": "jakarta.json.jmh.FactoryBenchmark.createValueString_viaJson", + "value": 69.55018600313181, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + }, + { + "name": "jakarta.json.jmh.FactoryBenchmark.createValueString_viaProvider", + "value": 477195.3373496084, + "unit": "ops/ms", + "extra": "iterations: 5\nforks: 1\nthreads: 1" + } + ] + } + ] + } +} \ No newline at end of file
diff --git a/dev/bench/index.html b/dev/bench/index.html new file mode 100644 index 0000000..6c88780 --- /dev/null +++ b/dev/bench/index.html
@@ -0,0 +1,281 @@ +<!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>