Skip to content

Commit 02b0bdf

Browse files
feat(vitest-plugin): allow perf profiling for vitest plugin
1 parent bee409e commit 02b0bdf

File tree

3 files changed

+64
-3
lines changed

3 files changed

+64
-3
lines changed

packages/vitest-plugin/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"bench": "vitest bench"
2929
},
3030
"dependencies": {
31-
"@codspeed/core": "workspace:^5.0.0"
31+
"@codspeed/core": "workspace:^5.0.0",
32+
"tinybench": "^2.9.0"
3233
},
3334
"peerDependencies": {
3435
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0",

packages/vitest-plugin/src/walltime/index.ts

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
import { setupCore, writeWalltimeResults } from "@codspeed/core";
1+
import {
2+
InstrumentHooks,
3+
setupCore,
4+
writeWalltimeResults,
5+
} from "@codspeed/core";
6+
import { Fn } from "tinybench";
27
import { type RunnerTestSuite } from "vitest";
38
import { NodeBenchmarkRunner } from "vitest/runners";
4-
import { patchRootSuiteWithFullFilePath } from "../common";
9+
import {
10+
isVitestTaskBenchmark,
11+
patchRootSuiteWithFullFilePath,
12+
} from "../common";
513
import { extractBenchmarkResults } from "./utils";
614

715
/**
@@ -15,6 +23,8 @@ export class WalltimeRunner extends NodeBenchmarkRunner {
1523
async runSuite(suite: RunnerTestSuite): Promise<void> {
1624
patchRootSuiteWithFullFilePath(suite);
1725

26+
this.populateBenchmarkUris(suite);
27+
1828
setupCore();
1929

2030
await super.runSuite(suite);
@@ -32,6 +42,53 @@ export class WalltimeRunner extends NodeBenchmarkRunner {
3242
);
3343
}
3444
}
45+
46+
private populateBenchmarkUris(suite: RunnerTestSuite, parentPath = ""): void {
47+
const currentPath = parentPath
48+
? `${parentPath}::${suite.name}`
49+
: suite.name;
50+
51+
for (const task of suite.tasks) {
52+
if (isVitestTaskBenchmark(task)) {
53+
const uri = `${currentPath}::${task.name}`;
54+
this.benchmarkUris.set(task.name, uri);
55+
} else if (task.type === "suite") {
56+
this.populateBenchmarkUris(task, currentPath);
57+
}
58+
}
59+
}
60+
61+
async importTinybench(): Promise<typeof import("tinybench")> {
62+
const tinybench = await super.importTinybench();
63+
64+
if (this.isTinybenchHookedWithCodspeed) {
65+
return tinybench;
66+
}
67+
this.isTinybenchHookedWithCodspeed = true;
68+
69+
const originalRun = tinybench.Task.prototype.run;
70+
const runner = this;
71+
tinybench.Task.prototype.run = async function () {
72+
const { fn } = this as { fn: Fn };
73+
74+
function __codspeed_root_frame__() {
75+
return fn();
76+
}
77+
(this as any).fn = __codspeed_root_frame__;
78+
79+
InstrumentHooks.startBenchmark();
80+
await originalRun.call(this);
81+
InstrumentHooks.stopBenchmark();
82+
83+
// Look up the URI by task name
84+
const uri = runner.benchmarkUris.get(this.name) || this.name;
85+
InstrumentHooks.setExecutedBenchmark(process.pid, uri);
86+
87+
return this;
88+
};
89+
90+
return tinybench;
91+
}
3592
}
3693

3794
export default WalltimeRunner;

pnpm-lock.yaml

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

0 commit comments

Comments
 (0)