From dc186589cb86ae140b76d43c01d78044e74f9bc5 Mon Sep 17 00:00:00 2001
From: Jonathan Ho <48591478+H01001000@users.noreply.github.com>
Date: Wed, 2 Nov 2022 23:13:11 +0800
Subject: [PATCH] feat: add benchmark to site (#2567)
* feat: add benchmark to site
* test
* remove test file
---
.github/workflows/commentBenchResult.yml | 3 +-
site/docs/benchmark.mdx | 9 ++
site/docusaurus.config.js | 4 +-
site/package-lock.json | 90 +++++++++++
site/package.json | 2 +
site/src/components/BenchmarkResultCharts.jsx | 147 ++++++++++++++++++
6 files changed, 252 insertions(+), 3 deletions(-)
create mode 100644 site/docs/benchmark.mdx
create mode 100644 site/src/components/BenchmarkResultCharts.jsx
diff --git a/.github/workflows/commentBenchResult.yml b/.github/workflows/commentBenchResult.yml
index 9d374c14e..b50bad0e2 100644
--- a/.github/workflows/commentBenchResult.yml
+++ b/.github/workflows/commentBenchResult.yml
@@ -80,6 +80,7 @@ jobs:
const fs = require('fs');
const commit_sha = fs.readFileSync('./sha', 'utf-8');
const repo = fs.readFileSync('./repo', 'utf-8');
+ if (repo.split('/')[1] === undefined) process.exit(0)
const pr = await github.rest.repos.listPullRequestsAssociatedWithCommit({
commit_sha: commit_sha.slice(0,-1),
owner: repo.split('/')[0],
@@ -88,7 +89,7 @@ jobs:
if (pr.data[0]) {
github.rest.issues.createComment({
issue_number: pr.data[0].number,
- owner: repo.split('/')[0],
+ owner: "discordeno",
repo: "discordeno",
body: `${{ env.MESSAGE }}`
})
diff --git a/site/docs/benchmark.mdx b/site/docs/benchmark.mdx
new file mode 100644
index 000000000..0b4d9c774
--- /dev/null
+++ b/site/docs/benchmark.mdx
@@ -0,0 +1,9 @@
+---
+sidebar_position: 5
+---
+
+# Benchmark
+
+import BenchmarkResultCharts from '@site/src/components/BenchmarkResultCharts'
+
+
\ No newline at end of file
diff --git a/site/docusaurus.config.js b/site/docusaurus.config.js
index f310ec6e0..1ee49127b 100644
--- a/site/docusaurus.config.js
+++ b/site/docusaurus.config.js
@@ -52,7 +52,7 @@ const config = {
type: "doc",
docId: "intro",
position: "left",
- label: "Tutorial",
+ label: "Docs",
},
{ to: "/blog", label: "Blog", position: "left" },
{
@@ -69,7 +69,7 @@ const config = {
title: "Docs",
items: [
{
- label: "Tutorial",
+ label: "Docs",
to: "/docs/intro",
},
],
diff --git a/site/package-lock.json b/site/package-lock.json
index 1785fdf1e..9199d82f7 100644
--- a/site/package-lock.json
+++ b/site/package-lock.json
@@ -13,9 +13,11 @@
"@docusaurus/preset-classic": "2.0.0-beta.15",
"@easyops-cn/docusaurus-search-local": "^0.21.4",
"@mdx-js/react": "^1.6.21",
+ "chart.js": "^2.9.4",
"clsx": "^1.1.1",
"prism-react-renderer": "^1.2.1",
"react": "^17.0.1",
+ "react-chartjs-2": "^2.11.2",
"react-dom": "^17.0.1"
},
"devDependencies": {
@@ -4359,6 +4361,32 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/chart.js": {
+ "version": "2.9.4",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz",
+ "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==",
+ "dependencies": {
+ "chartjs-color": "^2.1.0",
+ "moment": "^2.10.2"
+ }
+ },
+ "node_modules/chartjs-color": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
+ "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
+ "dependencies": {
+ "chartjs-color-string": "^0.6.0",
+ "color-convert": "^1.9.3"
+ }
+ },
+ "node_modules/chartjs-color-string": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
+ "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
+ "dependencies": {
+ "color-name": "^1.0.0"
+ }
+ },
"node_modules/cheerio": {
"version": "1.0.0-rc.10",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
@@ -8197,6 +8225,14 @@
"mkdirp": "bin/cmd.js"
}
},
+ "node_modules/moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/mrmime": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
@@ -9625,6 +9661,20 @@
"pure-color": "^1.2.0"
}
},
+ "node_modules/react-chartjs-2": {
+ "version": "2.11.2",
+ "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-2.11.2.tgz",
+ "integrity": "sha512-hcPS9vmRJeAALPPf0uo02BiD8BDm0HNmneJYTZVR74UKprXOpql+Jy1rVuj93rKw0Jfx77mkcRfXPxTe5K83uw==",
+ "dependencies": {
+ "lodash": "^4.17.19",
+ "prop-types": "^15.7.2"
+ },
+ "peerDependencies": {
+ "chart.js": "^2.3",
+ "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0",
+ "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
+ }
+ },
"node_modules/react-dev-utils": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz",
@@ -16089,6 +16139,32 @@
"resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
"integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg=="
},
+ "chart.js": {
+ "version": "2.9.4",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz",
+ "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==",
+ "requires": {
+ "chartjs-color": "^2.1.0",
+ "moment": "^2.10.2"
+ }
+ },
+ "chartjs-color": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
+ "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
+ "requires": {
+ "chartjs-color-string": "^0.6.0",
+ "color-convert": "^1.9.3"
+ }
+ },
+ "chartjs-color-string": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
+ "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
+ "requires": {
+ "color-name": "^1.0.0"
+ }
+ },
"cheerio": {
"version": "1.0.0-rc.10",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
@@ -18878,6 +18954,11 @@
"minimist": "^1.2.5"
}
},
+ "moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
+ },
"mrmime": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
@@ -19851,6 +19932,15 @@
"pure-color": "^1.2.0"
}
},
+ "react-chartjs-2": {
+ "version": "2.11.2",
+ "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-2.11.2.tgz",
+ "integrity": "sha512-hcPS9vmRJeAALPPf0uo02BiD8BDm0HNmneJYTZVR74UKprXOpql+Jy1rVuj93rKw0Jfx77mkcRfXPxTe5K83uw==",
+ "requires": {
+ "lodash": "^4.17.19",
+ "prop-types": "^15.7.2"
+ }
+ },
"react-dev-utils": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz",
diff --git a/site/package.json b/site/package.json
index 1855464de..32aee7880 100644
--- a/site/package.json
+++ b/site/package.json
@@ -20,9 +20,11 @@
"@docusaurus/preset-classic": "2.0.0-beta.15",
"@easyops-cn/docusaurus-search-local": "^0.21.4",
"@mdx-js/react": "^1.6.21",
+ "chart.js": "^2.9.4",
"clsx": "^1.1.1",
"prism-react-renderer": "^1.2.1",
"react": "^17.0.1",
+ "react-chartjs-2": "^2.11.2",
"react-dom": "^17.0.1"
},
"devDependencies": {
diff --git a/site/src/components/BenchmarkResultCharts.jsx b/site/src/components/BenchmarkResultCharts.jsx
new file mode 100644
index 000000000..ef040f82a
--- /dev/null
+++ b/site/src/components/BenchmarkResultCharts.jsx
@@ -0,0 +1,147 @@
+import { useColorMode } from "@docusaurus/theme-common";
+import React, { useEffect, useState } from "react";
+import { Line } from "react-chartjs-2";
+// 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",
+ benchmarkdotnet: "#178600",
+ customBiggerIsBetter: "#38ff38",
+ customSmallerIsBetter: "#ff3838",
+ _: "#333333",
+};
+
+const BenchmarkResultChart = ({ name, dataset, theme }) => {
+ 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,
+ },
+ },
+ ],
+ legend: {
+ labels: {
+ // This more specific font property overrides the global property
+ defaultFontColor: theme === "light" ? "#000000" : "#FFFFFF",
+ },
+ },
+ },
+ 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");
+ },
+ };
+ // console.log(theme);
+ return ;
+};
+
+export default function BenchmarkResultCharts() {
+ const { colorMode } = useColorMode();
+ const [data, setData] = useState();
+
+ useEffect(async () => {
+ if (!data) {
+ setData(
+ JSON.parse(
+ (await (await fetch(
+ "https://raw.githubusercontent.com/discordeno/discordeno/benchies/benchmarksResult/data.js",
+ )).text()).slice(24),
+ ),
+ );
+ }
+ }, []);
+
+ function collectBenchesPerTestCase(entries) {
+ const dataMap = 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 = dataMap.get(bench.name);
+ if (arr === undefined) {
+ dataMap.set(bench.name, [result]);
+ } else {
+ arr.push(result);
+ }
+ }
+ }
+ return dataMap;
+ }
+
+ return (data
+ ? Array.from(
+ collectBenchesPerTestCase(data.entries.Benchmark),
+ ([key, value]) => ({ benchName: key, benches: value }),
+ ).map((
+ bench,
+ index,
+ ) => (
+
+ ))
+ : <>>);
+}