1
1
import {
2
2
calculateQuantiles ,
3
+ InstrumentHooks ,
3
4
mongoMeasurement ,
4
5
msToNs ,
5
6
msToS ,
6
7
writeWalltimeResults ,
7
8
type Benchmark ,
8
9
type BenchmarkStats ,
9
10
} from "@codspeed/core" ;
10
- import { Bench , TaskResult } from "tinybench" ;
11
+ import { Bench , Fn , TaskResult } from "tinybench" ;
11
12
import { getTaskUri } from "./uri" ;
12
13
13
14
declare const __VERSION__ : string ;
@@ -28,21 +29,27 @@ export function runWalltimeBench(bench: Bench, rootCallingFile: string): void {
28
29
29
30
const benchmarks : Benchmark [ ] = [ ] ;
30
31
31
- // Run the bench naturally to collect TaskResult data
32
- const results = [ ] ;
33
-
34
32
// Collect and report walltime data
35
33
for ( const task of bench . tasks ) {
36
34
const uri = getTaskUri ( bench , task . name , rootCallingFile ) ;
37
35
36
+ // Override the function under test to add a static frame
37
+ const { fn } = task as unknown as { fn : Fn } ;
38
+ async function __codspeed_root_frame__ ( ) {
39
+ await fn ( ) ;
40
+ }
41
+ ( task as any ) . fn = __codspeed_root_frame__ ;
42
+
38
43
// run the warmup of the task right before its actual run
39
44
if ( bench . opts . warmup ) {
40
45
await task . warmup ( ) ;
41
46
}
47
+
42
48
await mongoMeasurement . start ( uri ) ;
43
- const taskResult = await task . run ( ) ;
49
+ InstrumentHooks . startBenchmark ( ) ;
50
+ await task . run ( ) ;
51
+ InstrumentHooks . stopBenchmark ( ) ;
44
52
await mongoMeasurement . stop ( uri ) ;
45
- results . push ( taskResult ) ;
46
53
47
54
if ( task . result ) {
48
55
// Convert tinybench result to BenchmarkStats format
@@ -67,8 +74,87 @@ export function runWalltimeBench(bench: Bench, rootCallingFile: string): void {
67
74
} ;
68
75
69
76
benchmarks . push ( benchmark ) ;
77
+ console . log ( ` ✔ Collected walltime data for ${ uri } ` ) ;
78
+ InstrumentHooks . setExecutedBenchmark ( process . pid , uri ) ;
79
+ } else {
80
+ console . warn ( ` ⚠ No result data available for ${ uri } ` ) ;
81
+ }
82
+ }
83
+
84
+ // Write results to JSON file using core function
85
+ if ( benchmarks . length > 0 ) {
86
+ writeWalltimeResults ( benchmarks ) ;
87
+ }
88
+
89
+ console . log (
90
+ `[CodSpeed] Done collecting walltime data for ${ bench . tasks . length } benches.`
91
+ ) ;
92
+ // Restore our custom run method
93
+ bench . run = originalRun ;
94
+
95
+ return bench . tasks ;
96
+ } ;
97
+
98
+ bench . runSync = ( ) => {
99
+ console . log (
100
+ `[CodSpeed] running with @codspeed/tinybench v${ __VERSION__ } (walltime mode)`
101
+ ) ;
102
+
103
+ // Store the original run method before we override it
104
+ const originalRun = bench . run ;
105
+
106
+ // Temporarily restore the original run to get actual benchmark results
107
+ const benchProto = Object . getPrototypeOf ( bench ) ;
108
+ const prototypeRun = benchProto . run ;
109
+ bench . run = prototypeRun ;
110
+
111
+ const benchmarks : Benchmark [ ] = [ ] ;
112
+
113
+ // Collect and report walltime data
114
+ for ( const task of bench . tasks ) {
115
+ const uri = getTaskUri ( bench , task . name , rootCallingFile ) ;
116
+
117
+ // run the warmup of the task right before its actual run
118
+ if ( bench . opts . warmup ) {
119
+ task . warmup ( ) ;
120
+ }
70
121
122
+ // Override the function under test to add a static frame
123
+ const { fn } = task as unknown as { fn : Fn } ;
124
+ function __codspeed_root_frame__ ( ) {
125
+ fn ( ) ;
126
+ }
127
+ ( task as any ) . fn = __codspeed_root_frame__ ;
128
+
129
+ InstrumentHooks . startBenchmark ( ) ;
130
+ task . runSync ( ) ;
131
+ InstrumentHooks . stopBenchmark ( ) ;
132
+
133
+ if ( task . result ) {
134
+ // Convert tinybench result to BenchmarkStats format
135
+ const stats = convertTinybenchResultToBenchmarkStats (
136
+ task . result ,
137
+ bench . opts . warmup ? bench . opts . warmupIterations ?? 0 : 0
138
+ ) ;
139
+
140
+ const benchmark : Benchmark = {
141
+ name : task . name ,
142
+ uri,
143
+ config : {
144
+ max_rounds : bench . opts . iterations ?? null ,
145
+ max_time_ns : bench . opts . time ? msToNs ( bench . opts . time ) : null ,
146
+ min_round_time_ns : null , // tinybench does not have an option for this
147
+ warmup_time_ns :
148
+ bench . opts . warmup && bench . opts . warmupTime
149
+ ? msToNs ( bench . opts . warmupTime )
150
+ : null ,
151
+ } ,
152
+ stats,
153
+ } ;
154
+
155
+ benchmarks . push ( benchmark ) ;
71
156
console . log ( ` ✔ Collected walltime data for ${ uri } ` ) ;
157
+ InstrumentHooks . setExecutedBenchmark ( process . pid , uri ) ;
72
158
} else {
73
159
console . warn ( ` ⚠ No result data available for ${ uri } ` ) ;
74
160
}
@@ -85,7 +171,7 @@ export function runWalltimeBench(bench: Bench, rootCallingFile: string): void {
85
171
// Restore our custom run method
86
172
bench . run = originalRun ;
87
173
88
- return results ;
174
+ return bench . tasks ;
89
175
} ;
90
176
}
91
177
0 commit comments