Skip to content

Commit a1b37a7

Browse files
committed
Add Deno benchmark runner and update perf docs
1 parent e7f553f commit a1b37a7

File tree

2 files changed

+89
-15
lines changed

2 files changed

+89
-15
lines changed

packages/api/perf/README.md

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,13 @@ expensive particular exported types from `packages/api/index.ts` are to check.
55
Each scenario lives in its own `.ts` file with a matching `tsconfig.*.json` so
66
that we can profile the types independently.
77

8-
## Prerequisites
9-
10-
The commands below assume you are inside the repo root and that the vendored
11-
TypeScript binary at `tsc` is available. Use `bash` to run the snippets
12-
exactlyas shown.
13-
148
## Quick Metrics
159

1610
Run the compiler with `--extendedDiagnostics` to get counts of type
1711
instantiations, memory usage, etc.
1812

1913
```bash
20-
tsc \
14+
deno run -A npm:typescript@5.8.3/bin/tsc \
2115
--project packages/api/perf/tsconfig.key.json \
2216
--extendedDiagnostics --pretty false
2317
```
@@ -43,7 +37,7 @@ profile…”.
4337

4438
```bash
4539
NODE_OPTIONS=--max-old-space-size=4096 \
46-
tsc \
40+
deno run -A npm:typescript@5.8.3/bin/tsc \
4741
--project packages/api/perf/tsconfig.ikeyable-cell.json \
4842
--generateCpuProfile packages/api/perf/traces/ikeyable-cell.cpuprofile
4943
```
@@ -63,7 +57,7 @@ exceed V8’s heap limit on the heavy scenarios.
6357
```bash
6458
mkdir -p packages/api/perf/traces/ikeyable-cell \
6559
&& NODE_OPTIONS=--max-old-space-size=4096 \
66-
tsc \
60+
deno run -A npm:typescript@5.8.3/bin/tsc \
6761
--project packages/api/perf/tsconfig.ikeyable-cell.json \
6862
--generateTrace packages/api/perf/traces/ikeyable-cell
6963
```
@@ -79,14 +73,19 @@ trace generation; it keeps the scenario minimal enough to succeed.
7973

8074
## Scripts / Analysis
8175

82-
There are no bespoke scripts yet; ad-hoc analysis can be performed with Node.js
83-
like so:
76+
To run every scenario in one go (and print a short summary for each), run:
77+
78+
```bash
79+
deno run -A packages/api/perf/run-benchmarks.ts
80+
```
81+
82+
For ad-hoc inspection of trace files you can also use Deno directly:
8483

8584
```bash
86-
deno -e 'const trace=require("./packages/api/perf/traces/ikeyable-cell/trace.json");\
87-
const totals=new Map();\
88-
for (const e of trace) if (e.ph==="X") totals.set(e.name,(totals.get(e.name)||0)+e.dur);\
89-
console.log([...totals.entries()].sort((a,b)=>b[1]-a[1]).slice(0,10));'
85+
deno eval 'import trace from "./packages/api/perf/traces/ikeyable-cell/trace.json" assert { type: "json" };\
86+
const totals = new Map();\
87+
for (const e of trace) if (e.ph === "X") totals.set(e.name, (totals.get(e.name) ?? 0) + e.dur);\
88+
console.log([...totals.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10));'
9089
```
9190

9291
Feel free to add your own utilities here if repeated analyses become necessary.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env -S deno run -A
2+
3+
const CONFIGS = [
4+
"tsconfig.baseline.json",
5+
"tsconfig.key.json",
6+
"tsconfig.anycell.json",
7+
"tsconfig.schema.json",
8+
"tsconfig.ikeyable-cell.json",
9+
"tsconfig.ikeyable-schema.json",
10+
"tsconfig.ikeyable-realistic.json",
11+
] as const;
12+
13+
const scriptDir = new URL(".", import.meta.url);
14+
const cwd = scriptDir.pathname;
15+
16+
function fromFileUrl(url: URL): string {
17+
if (url.protocol !== "file:") throw new TypeError("URL must be a file URL");
18+
const path = decodeURIComponent(url.pathname);
19+
if (Deno.build.os === "windows") {
20+
return path.slice(1).replaceAll("/", "\\");
21+
}
22+
return path;
23+
}
24+
25+
const tscPath = fromFileUrl(
26+
new URL(
27+
"../../../node_modules/.deno/typescript@5.8.3/node_modules/typescript/bin/tsc",
28+
import.meta.url,
29+
),
30+
);
31+
32+
const decoder = new TextDecoder();
33+
const encoder = new TextEncoder();
34+
35+
async function runScenario(config: string) {
36+
console.log(`# ${config}`);
37+
38+
const command = new Deno.Command(tscPath, {
39+
args: ["--project", config, "--extendedDiagnostics", "--pretty", "false"],
40+
cwd,
41+
});
42+
43+
const { code, stdout, stderr } = await command.output();
44+
if (code !== 0) {
45+
const err = decoder.decode(stderr);
46+
console.error(err);
47+
throw new Error(`Benchmark failed for ${config}`);
48+
}
49+
50+
const output = decoder.decode(stdout);
51+
console.log(output);
52+
53+
const summary: string[] = [];
54+
for (const line of output.split("\n")) {
55+
if (line.startsWith("Instantiations:")) {
56+
summary.push(line.trim());
57+
} else if (line.startsWith("Check time:")) {
58+
summary.push(line.trim());
59+
}
60+
}
61+
62+
if (summary.length > 0) {
63+
await Deno.stdout.write(
64+
encoder.encode(
65+
`${summary.join(" | ")}\n----------------------------------------\n\n`,
66+
),
67+
);
68+
} else {
69+
console.log("----------------------------------------\n");
70+
}
71+
}
72+
73+
for (const config of CONFIGS) {
74+
await runScenario(config);
75+
}

0 commit comments

Comments
 (0)