@@ -2,7 +2,6 @@ import { constants, writeFile } from "fs";
22import fs from "fs/promises" ;
33import path from "path" ;
44import { fileURLToPath , pathToFileURL } from "url" ;
5- import { withCodSpeed } from "@codspeed/tinybench-plugin" ;
65import { simpleGit } from "simple-git" ;
76import { Bench , hrtimeNow } from "tinybench" ;
87
@@ -277,11 +276,15 @@ function buildConfiguration(
277276 `baseline-${ baseline . name } `
278277 ) ;
279278 config . plugins = config . plugins || [ ] ;
280-
281279 if ( config . cache ) {
282280 config . cache . cacheDirectory = path . resolve ( config . output . path , ".cache" ) ;
283281 }
284-
282+ if ( watch ) {
283+ config . cache = {
284+ type : "memory" ,
285+ maxGenerations : 1
286+ } ;
287+ }
285288 return config ;
286289}
287290
@@ -319,12 +322,120 @@ const scenarios = [
319322
320323const baseOutputPath = path . join ( __dirname , "js" , "benchmark" ) ;
321324
322- const bench = withCodSpeed (
325+ const withCodSpeed = async ( /** @type {import("tinybench").Bench } */ bench ) => {
326+ const { Measurement, getGitDir, mongoMeasurement, setupCore, teardownCore } =
327+ await import ( "@codspeed/core" ) ;
328+
329+ if ( ! Measurement . isInstrumented ( ) ) {
330+ const rawRun = bench . run ;
331+ bench . run = async ( ) => {
332+ console . warn (
333+ `[CodSpeed] ${ bench . tasks . length } benches detected but no instrumentation found, falling back to tinybench`
334+ ) ;
335+ return await rawRun . bind ( bench ) ( ) ;
336+ } ;
337+ return bench ;
338+ }
339+
340+ const getStackTrace = ( belowFn ) => {
341+ const oldLimit = Error . stackTraceLimit ;
342+ Error . stackTraceLimit = Infinity ;
343+ const dummyObject = { } ;
344+ const v8Handler = Error . prepareStackTrace ;
345+ Error . prepareStackTrace = ( dummyObject , v8StackTrace ) => v8StackTrace ;
346+ Error . captureStackTrace ( dummyObject , belowFn || getStackTrace ) ;
347+ const v8StackTrace = dummyObject . stack ;
348+ Error . prepareStackTrace = v8Handler ;
349+ Error . stackTraceLimit = oldLimit ;
350+ return v8StackTrace ;
351+ } ;
352+
353+ const getCallingFile = ( ) => {
354+ const stack = getStackTrace ( ) ;
355+ let callingFile = stack [ 2 ] . getFileName ( ) ; // [here, withCodSpeed, actual caller]
356+ const gitDir = getGitDir ( callingFile ) ;
357+ if ( gitDir === undefined ) {
358+ throw new Error ( "Could not find a git repository" ) ;
359+ }
360+ if ( callingFile . startsWith ( "file://" ) ) {
361+ callingFile = fileURLToPath ( callingFile ) ;
362+ }
363+ return path . relative ( gitDir , callingFile ) ;
364+ } ;
365+
366+ const rawAdd = bench . add ;
367+ bench . add = ( name , fn , opts ) => {
368+ const callingFile = getCallingFile ( ) ;
369+ const uri = `${ callingFile } ::${ name } ` ;
370+ const options = { ...opts , uri } ;
371+ return rawAdd . bind ( bench ) ( name , fn , options ) ;
372+ } ;
373+ const rootCallingFile = getCallingFile ( ) ;
374+ bench . run = async function run ( ) {
375+ const iterations = bench . opts . iterations - 1 ;
376+ console . log ( "[CodSpeed] running" ) ;
377+ setupCore ( ) ;
378+ for ( const task of bench . tasks ) {
379+ await bench . opts . setup ?. ( task , "run" ) ;
380+ await task . fnOpts . beforeAll ?. call ( task ) ;
381+ const samples = [ ] ;
382+ async function iteration ( ) {
383+ try {
384+ await task . fnOpts . beforeEach ?. call ( task , "run" ) ;
385+ const start = bench . opts . now ( ) ;
386+ await task . fn ( ) ;
387+ samples . push ( bench . opts . now ( ) - start || 0 ) ;
388+ await task . fnOpts . afterEach ?. call ( this , "run" ) ;
389+ } catch ( err ) {
390+ if ( bench . opts . throws ) {
391+ throw err ;
392+ }
393+ }
394+ }
395+ while ( samples . length < iterations ) {
396+ await iteration ( ) ;
397+ }
398+ // Codspeed Measure
399+ const uri =
400+ task . opts && "uri" in task . options
401+ ? task . opts . uri
402+ : `${ rootCallingFile } ::${ task . name } ` ;
403+ await task . fnOpts . beforeEach ?. call ( task ) ;
404+ await mongoMeasurement . start ( uri ) ;
405+ await ( async function __codspeed_root_frame__ ( ) {
406+ Measurement . startInstrumentation ( ) ;
407+ await task . fn ( ) ;
408+ Measurement . stopInstrumentation ( uri ) ;
409+ } ) ( ) ;
410+ await mongoMeasurement . stop ( uri ) ;
411+ await task . fnOpts . afterEach ?. call ( task ) ;
412+ console . log ( `[Codspeed] ✔ Measured ${ uri } ` ) ;
413+ await task . fnOpts . afterAll ?. call ( task ) ;
414+
415+ await bench . opts . teardown ?. ( task , "run" ) ;
416+ task . processRunResult ( { latencySamples : samples } ) ;
417+ }
418+ teardownCore ( ) ;
419+ console . log ( `[CodSpeed] Done running ${ bench . tasks . length } benches.` ) ;
420+ return bench . tasks ;
421+ } ;
422+ return bench ;
423+ } ;
424+
425+ const bench = await withCodSpeed (
323426 new Bench ( {
324427 now : hrtimeNow ,
325428 throws : true ,
326429 warmup : true ,
327- time : 30000
430+ warmupIterations : 2 ,
431+ iterations : 8 ,
432+ setup ( task , mode ) {
433+ global . gc ( ) ;
434+ console . log ( `Setup (${ mode } mode): ${ task . name } ` ) ;
435+ } ,
436+ teardown ( task , mode ) {
437+ console . log ( `Teardown (${ mode } mode): ${ task . name } ` ) ;
438+ }
328439 } )
329440) ;
330441
@@ -393,6 +504,8 @@ async function registerSuite(bench, test, baselines) {
393504 bench . add (
394505 benchName ,
395506 async ( ) => {
507+ console . time ( `Time: ${ benchName } ` ) ;
508+
396509 const watchingPromise = new Promise ( ( res ) => {
397510 watchingResolve = res ;
398511 } ) ;
@@ -407,9 +520,11 @@ async function registerSuite(bench, test, baselines) {
407520 }
408521
409522 watchingPromise . then ( ( stats ) => {
523+ watchingResolve = undefined ;
524+
410525 // Construct and print stats to be more accurate with real life projects
411526 stats . toString ( ) ;
412-
527+ console . timeEnd ( `Time: ${ benchName } ` ) ;
413528 resolve ( ) ;
414529 } ) ;
415530 }
@@ -463,6 +578,8 @@ async function registerSuite(bench, test, baselines) {
463578 benchName ,
464579 async ( ) => {
465580 await new Promise ( ( resolve , reject ) => {
581+ console . time ( `Time: ${ benchName } ` ) ;
582+
466583 const baseCompiler = webpack ( config ) ;
467584
468585 baseCompiler . run ( ( err , stats ) => {
@@ -483,7 +600,7 @@ async function registerSuite(bench, test, baselines) {
483600
484601 // Construct and print stats to be more accurate with real life projects
485602 stats . toString ( ) ;
486-
603+ console . timeEnd ( `Time: ${ benchName } ` ) ;
487604 resolve ( ) ;
488605 } ) ;
489606 } ) ;
@@ -625,7 +742,7 @@ bench.addEventListener("cycle", (event) => {
625742 const collectBy = task . collectBy ;
626743 const allStats = statsByTests . get ( collectBy ) ;
627744
628- console . log ( `Done : ${ task . name } ${ confidence } (${ runs } runs sampled)` ) ;
745+ console . log ( `Cycle : ${ task . name } ${ confidence } (${ runs } runs sampled)` ) ;
629746
630747 const info = { ...latency , text, minConfidence, maxConfidence } ;
631748
@@ -646,11 +763,4 @@ bench.addEventListener("cycle", (event) => {
646763 ) ;
647764} ) ;
648765
649- // Fix for https://github.com/CodSpeedHQ/codspeed-node/issues/44
650- for ( const name of bench . tasks . map ( ( task ) => task . name ) ) {
651- const task = bench . getTask ( name ) ;
652-
653- task . opts = task . fnOpts ;
654- }
655-
656- await bench . run ( ) ;
766+ bench . run ( ) ;
0 commit comments