Skip to content

Commit

Permalink
Merge pull request #570 from gkjohnson/bench-redo
Browse files Browse the repository at this point in the history
Update benchmark log
  • Loading branch information
gkjohnson authored Aug 24, 2023
2 parents d1b731e + abbc3b0 commit ed02cca
Show file tree
Hide file tree
Showing 6 changed files with 543 additions and 542 deletions.
96 changes: 48 additions & 48 deletions .github/workflows/benchmark-report.yml
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Run Benchmark Report

on:
push:
branches: [ master ]
pull_request:
paths:
- 'src/**'
- 'package.json'
- 'benchmark/**'

permissions:
contents: read

jobs:
benchmark:
name: PR Benchmark
runs-on: ubuntu-latest

steps:
- name: Git checkout
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install
run: npm ci

- name: Run PR Benchmark
run: node ./benchmark/run-benchmark.js --json --long > pr-benchmark.json

- name: Checkout master
run: git checkout master

- name: Run Master Benchmark
run: node ./benchmark/run-benchmark.js --json --long > master-benchmark.json

- name: Log Difference
run: node ./benchmark/make-benchmark-log.js
# # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

# name: Run Benchmark Report

# on:
# push:
# branches: [ master ]
# pull_request:
# paths:
# - 'src/**'
# - 'package.json'
# - 'benchmark/**'

# permissions:
# contents: read

# jobs:
# benchmark:
# name: PR Benchmark
# runs-on: ubuntu-latest

# steps:
# - name: Git checkout
# uses: actions/checkout@v2
# with:
# fetch-depth: 0

# - name: Use Node.js
# uses: actions/setup-node@v2
# with:
# node-version: ${{ matrix.node-version }}
# cache: 'npm'

# - name: Install
# run: npm ci

# - name: Run PR Benchmark
# run: node ./benchmark/run-benchmark.js --json --long > pr-benchmark.json

# - name: Checkout master
# run: git checkout master

# - name: Run Master Benchmark
# run: node ./benchmark/run-benchmark.js --json --long > master-benchmark.json

# - name: Log Difference
# run: node ./benchmark/make-benchmark-log.js

174 changes: 174 additions & 0 deletions benchmark/bench.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { logTable } from './logTable.js';

let _maxTime = 3000;
let _maxIterations = 100;
let _prewarmIterations = 5;

const _beforeAll = [];
const _beforeEach = [];
const _afterAll = [];
const _afterEach = [];
const _bench = [];

const _suites = [];
const _tables = [];
let _current = null;

function findMedian( values ) {

values.sort( ( a, b ) => a - b );
const length = values.length;
if ( length % 2 === 1 ) {

return values[ Math.floor( length / 2 ) ];

} else {

const v1 = values[ length / 2 - 1 ];
const v2 = values[ length / 2 ];
return ( v1 + v2 ) / 2;

}

}

export function suite( name, cb ) {

cb();

_beforeAll.forEach( cb => cb() );
_current = [];
for ( let i = 0, l = _bench.length; i < l; i ++ ) {

_beforeEach.forEach( cb => cb() );

let iterations = 0;
let elapsed = 0;
let minTime = Infinity;
let maxTime = - Infinity;
let times = [];
let delta, start;
const { name, run, prerun, table } = _bench[ i ];

if ( run ) {

for ( let j = 0; j < _prewarmIterations; j ++ ) {

if ( prerun ) prerun();
run();

}

while ( elapsed < _maxTime ) {

if ( prerun ) prerun();
start = performance.now();
run();
delta = performance.now() - start;
elapsed += delta;

iterations ++;
maxTime = Math.max( maxTime, delta );
minTime = Math.min( minTime, delta );
times.push( delta );

if ( iterations >= _maxIterations ) break;

}

_afterEach.forEach( cb => cb() );

_current.push( {
name,
mean: elapsed / iterations,
median: findMedian( times ),
min: minTime,
max: maxTime,
iterations,
} );

} else {

_tables.push( {
name,
table: table(),
} );

}

}

_afterAll.forEach( cb => cb() );

_suites.push( { name, results: _current } );
_current = null;

logTable( _suites[ 0 ], [ 'mean', 'median', 'min', 'max' ] );

if ( _tables.length ) {

_suites[ 0 ].results = _tables;
delete _suites[ 0 ].name;
logTable( _suites[ 0 ] );

}

_suites.length = 0;

_afterAll.length = 0;
_afterEach.length = 0;
_beforeAll.length = 0;
_beforeEach.length = 0;
_bench.length = 0;
_tables.length = 0;

}

export function bench( name, prerun, run ) {

if ( run === undefined ) {

run = prerun;
prerun = undefined;

}

_bench.push( { prerun, run, name } );

}

export function beforeAll( cb ) {

_beforeAll.push( cb );

}

export function beforeEach( cb ) {

_beforeEach.push( cb );

}

export function afterEach( cb ) {

_afterEach.push( cb );

}

export function afterAll( cb ) {

_afterAll.push( cb );

}

export function appendTable( name, func ) {

_bench.push( { name, table: func } );

}

export function insertGap() {

appendTable( '', () => ( {} ) );

}
105 changes: 105 additions & 0 deletions benchmark/logTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@

const NAME_WIDTH = 35;
const COLUMN_WIDTH = 20;
const SEPARATOR = '|';
const SPACE = '&nbsp;&nbsp;&nbsp;';

function pad( str, len, char = ' ' ) {

let res = str;
while ( res.length < len ) {

res += char;

}

return res;

}

export function logObjectAsRows( info, exclude = [ 'name', 'iterations', 'table' ], depth = 1 ) {

for ( const key in info ) {

if ( exclude.includes( key ) ) continue;

if ( typeof info[ key ] === 'object' ) {

logObjectAsRows( info[ key ], exclude, depth + 1 );

} else {

const value = typeof info[ key ] === 'string' ? info[ key ] : `${ info[ key ].toFixed( 5 ) } ms`;
console.log( SEPARATOR + pad( pad( '', depth, SPACE ) + key, NAME_WIDTH ) + SEPARATOR + pad( value, COLUMN_WIDTH ) + SEPARATOR );

}

}

}

export function logTable( info, columns = [] ) {

if ( info.name ) {

console.log( `**${ info.name }**` );

}

if ( columns.length > 0 ) {

let row = SEPARATOR + pad( '', NAME_WIDTH ) + SEPARATOR;
let split = '|---|';
columns.forEach( key => {

row += pad( key, COLUMN_WIDTH ) + SEPARATOR;
split += '---|';

} );
console.log( row );
console.log( split );

} else {

console.log( '| | Values |' );
console.log( '|---|---|' );

}

info.results.forEach( data => {

if ( data.table ) {

console.log( SEPARATOR + pad( data.name, NAME_WIDTH ) + SEPARATOR );
logObjectAsRows( data.table );

} else if ( columns.length > 0 ) {

let row = SEPARATOR + pad( data.name, NAME_WIDTH ) + SEPARATOR;
columns.forEach( key => {

if ( ! ( key in data ) ) {

row += pad( `--`, COLUMN_WIDTH ) + SEPARATOR;

} else {

const value = typeof data[ key ] === 'string' ? data[ key ] : `${ data[ key ].toFixed( 5 ) } ms`;
row += pad( value, COLUMN_WIDTH ) + SEPARATOR;

}

} );
console.log( row );

} else {

console.log( SEPARATOR + pad( data.name, NAME_WIDTH ) + SEPARATOR );
logObjectAsRows( data );

}

} );
console.log();

}
Loading

0 comments on commit ed02cca

Please sign in to comment.