@@ -3,6 +3,7 @@ import { init as initDotNet } from "./dotnet/init.mjs";
33import { init as initDotNetLLVM } from "./dotnet-llvm/init.mjs" ;
44import { init as initGo } from "./go/init.mjs" ;
55import { init as initRust } from "./rust/init.mjs" ;
6+ import { init as initZig } from "./zig/init.mjs" ;
67import * as fixtures from "./fixtures.mjs" ;
78
89/**
@@ -17,23 +18,28 @@ const baseline = new Map;
1718
1819if ( ! lang || lang . toLowerCase ( ) === "rust" )
1920 await run ( "Rust" , await initRust ( ) ) ;
21+ if ( ! lang || lang . toLowerCase ( ) === "zig" )
22+ await run ( "Zig" , await initZig ( ) ) ;
2023if ( ! lang || lang . toLowerCase ( ) === "llvm" )
2124 await run ( ".NET LLVM" , await initDotNetLLVM ( ) ) ;
22- if ( ! lang || lang . toLowerCase ( ) === "net" )
23- await run ( ".NET AOT" , await initDotNet ( ) ) ;
2425if ( ! lang || lang . toLowerCase ( ) === "boot" )
2526 await run ( "Bootsharp" , await initBootsharp ( ) ) ;
27+ if ( ! lang || lang . toLowerCase ( ) === "net" )
28+ await run ( ".NET AOT" , await initDotNet ( ) ) ;
2629if ( ! lang || lang . toLowerCase ( ) === "go" )
2730 await run ( "Go" , await initGo ( ) ) ;
2831
2932/** @param {string } lang
3033 * @param {Exports } exports */
3134async function run ( lang , exports ) {
3235 console . log ( `\n\nBenching ${ lang } ...\n` ) ;
36+
37+ global . gc ( ) ;
3338 await new Promise ( r => setTimeout ( r , 100 ) ) ;
34- bench ( "Echo number" , exports . echoNumber , 100 , 3 , 1000 , fixtures . getNumber ( ) ) ;
35- bench ( "Echo struct" , exports . echoStruct , 100 , 3 , 100 , fixtures . getStruct ( ) ) ;
39+
3640 bench ( "Fibonacci" , ( ) => exports . fi ( 33 ) , 100 , 3 , 1 ) ;
41+ bench ( "Echo number" , exports . echoNumber , 100 , 3 , 100000 , fixtures . getNumber ( ) ) ;
42+ bench ( "Echo struct" , exports . echoStruct , 100 , 3 , 1000 , fixtures . getStruct ( ) ) ;
3743}
3844
3945function bench ( name , fn , iters , warms , loops , expected = undefined ) {
@@ -53,19 +59,27 @@ function bench(name, fn, iters, warms, loops, expected = undefined) {
5359 for ( let l = 0 ; l < loops ; l ++ ) fn ( ) ;
5460 if ( i >= 0 ) results . push ( performance . now ( ) - start ) ;
5561 }
56- let media = median ( results ) ;
57-
62+ const med = getMedian ( results , 0.3 ) ;
63+ const dev = getDeviation ( results ) ;
5864 if ( baseline . has ( name ) ) {
59- console . log ( `${ name } : ${ ( media / baseline . get ( name ) ) . toFixed ( 1 ) } ` ) ;
65+ console . log ( `${ name } : ${ ( med / baseline . get ( name ) ) . toFixed ( 1 ) } ${ dev } ` ) ;
6066 } else {
61- baseline . set ( name , media ) ;
62- console . log ( `${ name } : ${ media . toFixed ( 3 ) } ms` ) ;
67+ baseline . set ( name , med ) ;
68+ console . log ( `${ name } : ${ med . toFixed ( 3 ) } ms ${ dev } ` ) ;
6369 }
6470}
6571
66- function median ( numbers ) {
72+ function getMedian ( numbers , trim ) {
6773 const sorted = [ ...numbers ] . sort ( ( a , b ) => a - b ) ;
68- const middle = Math . floor ( sorted . length / 2 ) ;
69- if ( sorted . length % 2 === 1 ) return sorted [ middle ] ;
70- return ( sorted [ middle - 1 ] + sorted [ middle ] ) / 2 ;
74+ const trimAmount = Math . floor ( sorted . length * trim ) ;
75+ const trimmedArray = sorted . slice ( trimAmount , sorted . length - trimAmount ) ;
76+ return trimmedArray . reduce ( ( sum , val ) => sum + val , 0 ) / trimmedArray . length ;
77+ }
78+
79+ function getDeviation ( numbers ) {
80+ const mean = numbers . reduce ( ( sum , val ) => sum + val , 0 ) / numbers . length ;
81+ const sqr = numbers . map ( value => Math . pow ( value - mean , 2 ) ) ;
82+ const variance = sqr . reduce ( ( sum , val ) => sum + val , 0 ) / numbers . length ;
83+ const dev = Math . sqrt ( variance ) ;
84+ return `±${ ( ( dev / mean ) * 100 ) . toFixed ( 0 ) } %` ;
7185}
0 commit comments