Skip to content

Commit d66c8d7

Browse files
authored
feat: add benchmarks (#35)
* add benchmarks * add benchmarks to ci * using process.execPath
1 parent d3d8c5d commit d66c8d7

File tree

5 files changed

+101
-1
lines changed

5 files changed

+101
-1
lines changed

.github/workflows/ci.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,27 @@ jobs:
6262

6363
- name: Type-check
6464
run: pnpm type-check
65+
66+
benchmark:
67+
name: Benchmarks
68+
runs-on: ubuntu-latest
69+
70+
steps:
71+
- name: Checkout
72+
uses: actions/checkout@v4
73+
74+
- name: Install pnpm
75+
uses: pnpm/[email protected]
76+
77+
- name: Set node version to 20
78+
uses: actions/setup-node@v4
79+
with:
80+
node-version: 20
81+
registry-url: https://registry.npmjs.org/
82+
cache: pnpm
83+
84+
- name: Install deps
85+
run: pnpm install
86+
87+
- name: Run benchmarks
88+
run: pnpm benchmark

benchmarks/completion.bench.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Bench } from 'tinybench';
2+
import { promisify } from 'node:util';
3+
import { exec as execCb } from 'node:child_process';
4+
5+
const exec = promisify(execCb);
6+
7+
const bench = new Bench({ time: 2000 });
8+
9+
const cmdPrefix = `${process.execPath} ./dist/examples/demo.t.js complete --`;
10+
11+
async function run(cmd: string) {
12+
await exec(cmd);
13+
}
14+
15+
bench.add('command completion', async () => {
16+
await run(`${cmdPrefix} d`);
17+
});
18+
19+
bench.add('option completion', async () => {
20+
await run(`${cmdPrefix} dev --p`);
21+
});
22+
23+
bench.add('option value completion', async () => {
24+
await run(`${cmdPrefix} dev --port ""`);
25+
});
26+
27+
bench.add('config value completion', async () => {
28+
await run(`${cmdPrefix} --config ""`);
29+
});
30+
31+
bench.add('no match', async () => {
32+
await run(`${cmdPrefix} xyz`);
33+
});
34+
35+
async function runBenchmarks() {
36+
await bench.run();
37+
38+
console.table(
39+
bench.tasks.map((task) => {
40+
const hz = task.result?.hz;
41+
const derivedMs =
42+
typeof hz === 'number' && hz > 0 ? 1000 / hz : undefined;
43+
const mean = task.result?.mean;
44+
return {
45+
name: task.name,
46+
'ops/sec': hz ? Math.round(hz).toLocaleString() : 'N/A',
47+
'avg (ms)':
48+
derivedMs !== undefined
49+
? derivedMs.toFixed(3)
50+
: mean !== undefined
51+
? (mean * 1000).toFixed(3)
52+
: 'N/A',
53+
};
54+
})
55+
);
56+
}
57+
58+
if (process.argv[1]?.endsWith('completion.bench.ts')) {
59+
runBenchmarks().catch(console.error);
60+
}
61+
62+
export { runBenchmarks };

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"build": "tsdown",
1616
"prepare": "pnpm build",
1717
"lint": "eslint src \"./*.ts\"",
18-
"test-cli": "tsx bin/cli.ts"
18+
"benchmark": "tsx benchmarks/completion.bench.ts"
1919
},
2020
"files": [
2121
"dist"
@@ -30,6 +30,7 @@
3030
"commander": "^13.1.0",
3131
"eslint-config-prettier": "^10.0.1",
3232
"prettier": "^3.5.2",
33+
"tinybench": "^4.0.1",
3334
"tsdown": "^0.9.7",
3435
"tsx": "^4.19.1",
3536
"typescript": "^5.7.3",

pnpm-lock.yaml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tsdown.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ export default defineConfig({
77
'src/cac.ts',
88
'src/commander.ts',
99
'bin/cli.ts',
10+
'examples/demo.t.ts',
11+
'examples/demo.cac.ts',
12+
'examples/demo.citty.ts',
13+
'examples/demo.commander.ts',
1014
],
1115
format: ['esm'],
1216
dts: true,

0 commit comments

Comments
 (0)