import { createBenchmark , getOptions , now , sortResults , wait } from './utils' ; class BencheeSuite implements BencheeSuite { benchmarks : Benchee . BenchmarkGroup ; isRunning : boolean ; options : Benchee . Options ; results : Benchee . Results ; constructor ( passedOptions ? ) { this . benchmarks = { } ; this . isRunning = false ; this . options = getOptions ( passedOptions ) ; this . results = { } ; } param benchmark param stats _onResult ( benchmark , error , stats ) { const { benchmarks , options : { onComplete , onGroupComplete , onResult } , results , } = this ; const result = { error , stats , name : benchmark . name , } ; results [ benchmark . group ] . push ( result ) ; if ( typeof onResult === 'function' ) { onResult ( result ) ; } if ( typeof onGroupComplete === 'function' && ! benchmarks [ benchmark . group ] . length ) { onGroupComplete ( { group : benchmark . group , results : sortResults ( results [ benchmark . group ] ) , } ) ; } if ( typeof onComplete === 'function' ) { for ( const group in benchmarks ) { if ( benchmarks [ group ] . length ) { return ; } } onComplete ( results ) ; } } param benchmarkOptions async _runBenchmark ( benchmarkOptions ) { const { options : { minIterations , minTime , type } , } = this ; const { benchmark , iterations = minIterations , startTime : passedStartTime , } = benchmarkOptions ; const runs = Math . max ( iterations , 1 ) ; let endTime ; const startTime = passedStartTime || now ( ) ; try { this . _runBenchmarkIterations ( benchmark , runs ) ; endTime = now ( ) ; } catch ( error ) { endTime = now ( ) ; const elapsed = endTime - startTime ; this . _onResult ( benchmark , error , { elapsed , endTime , startTime , iterations : benchmark . iterations , ops : 0 , tpe : 0 , } ) ; return ; } benchmark . iterations += runs ; const elapsed = Math . max ( endTime - startTime , 1 ) ; if ( type !== 'fixed' && elapsed < minTime ) { await wait ( ) ; await this . _runBenchmark ( { benchmark , startTime , iterations : ~ ~ ( ( ( runs * minTime ) / elapsed ) * 0.9 ) , } ) ; return ; } const elapsedInSeconds = elapsed / 1000 ; this . _onResult ( benchmark , null , { elapsed , endTime , startTime , iterations : benchmark . iterations , ops : ~ ~ ( benchmark . iterations / elapsedInSeconds ) , tpe : elapsed / benchmark . iterations , } ) ; } param benchmark param runs _runBenchmarkIterations ( benchmark , runs ) { let pending = runs ; while ( pending -- ) { benchmark . fn ( ) ; } } param groupBenchmarks param group async _runGroup ( groupBenchmarks , group ? ) { if ( ! groupBenchmarks . length ) { return Promise . resolve ( ) ; } const { options : { delay , onGroupStart } , } = this ; if ( group && typeof onGroupStart === 'function' ) { onGroupStart ( group ) ; } while ( groupBenchmarks . length ) { await wait ( delay ) ; await this . _runBenchmark ( { benchmark : groupBenchmarks . shift ( ) } ) ; } } param name param benchmarkGroup param benchmarkFn add ( name , benchmarkGroup , benchmarkFn ? ) { const { benchmarks , results } = this ; const benchmark = createBenchmark ( name , benchmarkGroup , benchmarkFn ) ; const { group } = benchmark ; if ( ! benchmarks [ group ] ) { benchmarks [ group ] = [ ] ; results [ group ] = [ ] ; } benchmarks [ group ] . push ( benchmark ) ; return this ; } /**
     * run the benchmarks in the queue
     */ async run ( ) { const { benchmarks , isRunning , results } = this ; if ( isRunning ) { throw new Error ( 'Benchee is already running.' ) ; } this . isRunning = true ; for ( const group in benchmarks ) { await this . _runGroup ( benchmarks [ group ] , group ) ; } this . isRunning = false ; return results ; } } export default BencheeSuite ;