import * as benchmark from 'benchmark' ; import { toBigIntBE , toBigIntLE , toBufferBE , toBufferLE } from './index' ; const BN = require ( 'bn.js' ) ; const suite = new benchmark . Suite ( ) ; interface BenchmarkRun { name : string ; hz : number ; stats : benchmark . Stats ; } suite . add ( 'no-op' , ( ) => { } ) ; const smallHex = 'deadbeef' ; const smallString = `0x${ smallHex }` ; const smallBuf = Buffer . from ( smallHex , 'hex' ) ; suite . add ( 'bigint from hex string (small)' , ( ) => { return BigInt ( smallString ) ; } ) ; suite . add ( 'bigint from hex string from buffer (small)' , ( ) => { return BigInt ( `0x${ smallBuf . toString ( 'hex' ) }` ) ; } ) ; suite . add ( 'BN from hex string from buffer (small)' , ( ) => { return new BN ( smallBuf . toString ( 'hex' ) , 16 ) ; } ) ; suite . add ( 'LE bigint-buffer ToBigInt (small)' , ( ) => { return toBigIntLE ( smallBuf ) ; } ) ; suite . add ( 'BE bigint-buffer ToBigInt (small)' , ( ) => { return toBigIntBE ( smallBuf ) ; } ) ; const midHex = 'badc0ffee0ddf00d' ; const midString = `0x${ midHex }` ; const midBuf = Buffer . from ( midHex , 'hex' ) ; suite . add ( 'bigint from hex string (mid, aligned)' , ( ) => { return BigInt ( midString ) ; } ) ; suite . add ( 'bigint from hex string from buffer (mid, aligned)' , ( ) => { return BigInt ( `0x${ midBuf . toString ( 'hex' ) }` ) ; } ) ; suite . add ( 'BN from hex string from buffer (mid, aligned)' , ( ) => { return new BN ( midBuf . toString ( 'hex' ) , 16 ) ; } ) ; suite . add ( 'LE bigint-buffer ToBigInt (mid, aligned)' , ( ) => { return toBigIntLE ( midBuf ) ; } ) ; suite . add ( 'BE bigint-buffer ToBigInt (mid, aligned)' , ( ) => { return toBigIntBE ( midBuf ) ; } ) ; const hugeHex = 'badc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00d' ; const hugeString = `0x${ hugeHex }` ; const hugeBuf = Buffer . from ( hugeHex , 'hex' ) ; suite . add ( 'bigint from hex string (huge)' , ( ) => { return BigInt ( hugeString ) ; } ) ; suite . add ( 'bigint from hex string from buffer (huge)' , ( ) => { return BigInt ( `0x${ hugeBuf . toString ( 'hex' ) }` ) ; } ) ; suite . add ( 'BN from hex string from buffer (huge)' , ( ) => { return new BN ( hugeBuf . toString ( 'hex' ) , 16 ) ; } ) ; suite . add ( 'LE bigint-buffer ToBigInt (huge)' , ( ) => { return toBigIntLE ( hugeBuf ) ; } ) ; suite . add ( 'BE bigint-buffer ToBigInt (huge)' , ( ) => { return toBigIntBE ( hugeBuf ) ; } ) ; const bigIntToBufferWithStringBE = ( int , width ) : Buffer => { const hex = int . toString ( 16 ) ; return Buffer . from ( hex . padStart ( width * 2 , '0' ) . slice ( 0 , width * 2 ) , 'hex' ) ; } ; const bigIntToBufferWithStringLE = ( int , width ) : Buffer => { const hex = int . toString ( 16 ) ; const buffer = Buffer . from ( hex . padStart ( width * 2 , '0' ) . slice ( 0 , width * 2 ) , 'hex' ) ; buffer . reverse ( ) ; return buffer ; } ; const smallValue = 12345678n ; suite . add ( 'LE bigint to hex string to buffer (small)' , ( ) => { return bigIntToBufferWithStringLE ( smallValue , 8 ) ; } ) ; suite . add ( 'BE bigint to hex string to buffer (small)' , ( ) => { return bigIntToBufferWithStringBE ( smallValue , 8 ) ; } ) ; const bnSmallValue = new BN ( '12345678' , 10 ) ; suite . add ( 'BN to buffer (small)' , ( ) => { return bnSmallValue . toBuffer ( 8 ) ; } ) ; suite . add ( 'LE bigint-buffer to buffer (small)' , ( ) => { return toBufferLE ( smallValue , 8 ) ; } ) ; suite . add ( 'BE bigint-buffer to buffer (small)' , ( ) => { return toBufferBE ( smallValue , 8 ) ; } ) ; const largeValue = 0xbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dn ; suite . add ( 'LE bigint to hex string to buffer (large)' , ( ) => { return bigIntToBufferWithStringLE ( largeValue , 24 ) ; } ) ; suite . add ( 'BE bigint to hex string to buffer (large)' , ( ) => { return bigIntToBufferWithStringBE ( largeValue , 24 ) ; } ) ; const bnLargeValue = new BN ( 'badc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00d' , 16 ) ; suite . add ( 'BN to buffer (large)' , ( ) => { return bnLargeValue . toBuffer ( 24 ) ; } ) ; suite . add ( 'LE bigint-buffer to buffer (large)' , ( ) => { return toBufferLE ( largeValue , 24 ) ; } ) ; suite . add ( 'BE bigint-buffer to buffer (large)' , ( ) => { return toBufferBE ( largeValue , 24 ) ; } ) ; suite . add ( 'LE bigint to hex string to buffer (large)' , ( ) => { return bigIntToBufferWithStringLE ( largeValue , 8 ) ; } ) ; suite . add ( 'BE bigint to hex string to buffer (large)' , ( ) => { return bigIntToBufferWithStringBE ( largeValue , 8 ) ; } ) ; suite . add ( 'LE bigint-buffer to buffer (large, truncated)' , ( ) => { return toBufferLE ( largeValue , 8 ) ; } ) ; suite . add ( 'BE bigint-buffer to buffer (large, truncated)' , ( ) => { return toBufferBE ( largeValue , 8 ) ; } ) ; const b1 = Buffer . from ( '0123456789ABCDEF0123456789ABCDEF' , 'hex' ) ; const b2 = Buffer . from ( '0123456789ABCDEF0123456789ABCDEF' , 'hex' ) ; const bn1 = new BN ( '0123456789ABCDEF0123456789ABCDEF' , 'hex' ) ; const bn2 = new BN ( '0123456789ABCDEF0123456789ABCDEF' , 'hex' ) ; const n1 = 0x0123456789abcdef0123456789abcdefn ; const n2 = 0x0123456789abcdef0123456789abcdefn ; suite . add ( 'Buffer equality comparison' , ( ) => { return b1 . compare ( b2 ) === 0 ; } ) ; suite . add ( 'BN equality comparison' , ( ) => { return bn1 . eq ( bn2 ) ; } ) ; suite . add ( 'bigint equality comparison' , ( ) => { return n1 === n2 ; } ) ; suite . add ( 'BN multiply' , ( ) => { return bn1 . mul ( bn2 ) ; } ) ; suite . add ( 'bigint multiply' , ( ) => { return n1 * n2 ; } ) ; suite . on ( 'cycle' , ( event ) => { const benchmarkRun = event . target as BenchmarkRun ; const stats = benchmarkRun . stats as benchmark . Stats ; const meanInNanos = ( stats . mean * 1000000000 ) . toFixed ( 2 ) ; const stdDevInNanos = ( stats . deviation * 1000000000 ) . toFixed ( 3 ) ; const runs = stats . sample . length ; const ops = benchmarkRun . hz . toFixed ( benchmarkRun . hz < 100 ? 2 : 0 ) ; const err = stats . rme . toFixed ( 2 ) ; console . log ( `${ benchmarkRun . name }: ${ ops }±${ err }% ops/s ${ meanInNanos }±${ stdDevInNanos } ns/op (${ runs } run${ runs === 0 ? '' : 's' })` ) ; } ) ; suite . run ( ) ;