Skip to content

Commit 02754a2

Browse files
authored
Merge pull request #52 from bombshell-dev/bench/startup-timing
bench: add WASM init and startup timing benchmarks
2 parents c55a136 + 266259e commit 02754a2

5 files changed

Lines changed: 145 additions & 6 deletions

File tree

.github/workflows/benchmark.yml

Lines changed: 107 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ concurrency:
1616
cancel-in-progress: true
1717

1818
jobs:
19-
benchmarks:
20-
name: Run benchmarks
19+
build:
20+
name: Build
2121
runs-on: ubuntu-latest
2222
permissions:
2323
contents: read # clone repo
24-
id-token: write # upload benchmark results to codspeed
2524
steps:
2625
- name: Checkout
2726
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -34,15 +33,73 @@ jobs:
3433
with:
3534
deno-version: v2.x
3635

37-
- name: Setup Node
38-
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
36+
- name: Cache WASM
37+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
38+
id: wasm-cache
3939
with:
40-
node-version: 22
40+
path: |
41+
clayterm.wasm
42+
wasm.ts
43+
key: wasm-${{ hashFiles('Makefile', 'src/**', 'tasks/bundle-wasm.ts') }}
4144

4245
- name: Build WASM
46+
if: steps.wasm-cache.outputs.cache-hit != 'true'
4347
run: make
4448

49+
- name: Cache dependencies
50+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
51+
id: deno-cache
52+
with:
53+
path: node_modules
54+
key: deno-${{ hashFiles('deno.lock') }}
55+
56+
- name: Install dependencies
57+
if: steps.deno-cache.outputs.cache-hit != 'true'
58+
run: deno install
59+
60+
- name: Upload build artifact
61+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
62+
with:
63+
name: bench-build
64+
retention-days: 1
65+
path: wasm.ts
66+
67+
simulation:
68+
name: Run benchmarks (simulation)
69+
needs: build
70+
runs-on: ubuntu-latest
71+
permissions:
72+
contents: read # clone repo
73+
id-token: write # upload benchmark results to codspeed
74+
75+
steps:
76+
- name: Checkout
77+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
78+
79+
- name: Setup Deno
80+
uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4
81+
with:
82+
deno-version: v2.x
83+
84+
- name: Setup Node
85+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
86+
with:
87+
node-version: 24
88+
89+
- name: Download build artifact
90+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
91+
with:
92+
name: bench-build
93+
94+
- name: Restore dependencies
95+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
96+
id: deno-cache
97+
with:
98+
path: node_modules
99+
key: deno-${{ hashFiles('deno.lock') }}
100+
45101
- name: Install dependencies
102+
if: steps.deno-cache.outputs.cache-hit != 'true'
46103
run: deno install
47104

48105
- name: Run benchmarks
@@ -51,3 +108,47 @@ jobs:
51108
mode: simulation
52109
# IMPORTANT! deno task bench fails in CI due to incompatible V8 bindings
53110
run: node bench/mod.ts
111+
112+
walltime:
113+
name: Run benchmarks (walltime)
114+
needs: build
115+
runs-on: codspeed-macro
116+
permissions:
117+
contents: read # clone repo
118+
id-token: write # upload benchmark results to codspeed
119+
120+
steps:
121+
- name: Checkout
122+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
123+
124+
- name: Setup Deno
125+
uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4
126+
with:
127+
deno-version: v2.x
128+
129+
- name: Setup Node
130+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
131+
with:
132+
node-version: 24
133+
134+
- name: Download build artifact
135+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
136+
with:
137+
name: bench-build
138+
139+
- name: Restore dependencies
140+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
141+
id: deno-cache
142+
with:
143+
path: node_modules
144+
key: deno-codspeed-${{ runner.arch }}-${{ hashFiles('deno.lock') }}
145+
146+
- name: Install dependencies
147+
if: steps.deno-cache.outputs.cache-hit != 'true'
148+
run: deno install
149+
150+
- name: Run process startup benchmarks
151+
uses: CodSpeedHQ/action@9d332c4d90b43981c3e55ae8e38e68709996240f # v4.17.0
152+
with:
153+
mode: walltime
154+
run: node bench/startup.bench.ts

bench/fixtures/create-term/mod.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { createTerm } from "../../../term.ts";
2+
3+
await createTerm({ width: 80, height: 24 });
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { createTerm } from "../../../term.ts";
2+
import { close, grow, open, text } from "../../../ops.ts";
3+
4+
let term = await createTerm({ width: 80, height: 24 });
5+
term.render([
6+
open("root", { layout: { width: grow(), height: grow(), direction: "ttb" } }),
7+
text("Hello, World!"),
8+
close(),
9+
]);

bench/fixtures/utils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { fileURLToPath } from "node:url";
2+
import { spawn } from "node:child_process";
3+
4+
export const fixture = (name: string) => {
5+
return new URL(`./${name}/mod.ts`, import.meta.url);
6+
};
7+
8+
export const spawnFixture = (name: string): Promise<void> =>
9+
new Promise((resolve) => {
10+
spawn(process.execPath, [
11+
...process.execArgv,
12+
fileURLToPath(fixture(name)),
13+
], { stdio: "ignore" }).on("close", resolve);
14+
});

bench/startup.bench.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Bench } from "tinybench";
2+
import { withCodSpeed } from "@codspeed/tinybench-plugin";
3+
import { spawnFixture } from "./fixtures/utils.ts";
4+
5+
let bench = withCodSpeed(new Bench({ name: "startup" }));
6+
7+
bench
8+
.add("createTerm", () => spawnFixture("create-term"))
9+
.add("time to first render", () => spawnFixture("render-minimal"));
10+
11+
await bench.run();
12+
console.table(bench.table());

0 commit comments

Comments
 (0)