import { summary, run, bench } from 'mitata'; // Warmup (de-optimize `bench()` calls) bench('noop', () => { }); bench('noop2', () => { }); // Example benchmark /*summary(() => { const fn = () => null const fnAlt = function() {} function fnBasic() {} const fnAltWithReturn = function() { return null } function fnBasicWithReturn() { return null } bench('Reject with uncached error handler', async () => await Promise.reject().catch(() => null)); bench('Reject with cached error handler', async () => await Promise.reject().catch(fn)); bench('TT Reject with uncached error handler', () => Promise.reject().catch(() => null)); bench('TT Reject with cached error handler', () => Promise.reject().catch(fnAlt)); bench('TT Reject with cached basic error handler', () => Promise.reject().catch(fnBasic)); bench('TT Reject with cached error handler with return', () => Promise.reject().catch(fnAltWithReturn)); bench('TT Reject with cached basic error handler with return ', () => Promise.reject().catch(fnBasicWithReturn)); });*/ /* summary(() => { function triple () { const bla = Math.round(Math.random()) ? true : null return bla === null } function doubleNull () { const bla = Math.round(Math.random()) ? true : null return bla == null } function doubleUndefined () { const bla = Math.round(Math.random()) ? true : undefined return bla == null } bench('null === null', triple); bench('null == null', doubleNull); bench('undefined == null', doubleUndefined); bench('2x null === null', triple); bench('2x null == null', doubleNull); bench('2x undefined == null', doubleUndefined); }) summary(() => { function triple () { const bla = false ? true : null return bla === null } function doubleNull () { const bla = false ? true : null return bla == null } function doubleUndefined () { const bla = false ? true : undefined return bla == null } bench('const null === null', triple); bench('const null == null', doubleNull); bench('const undefined == null', doubleUndefined); bench('const 2x null === null', triple); bench('const 2x null == null', doubleNull); bench('const 2x undefined == null', doubleUndefined); })*/ function printCurrentStatus(fn) { let opt = %GetOptimizationStatus(fn) console.log(`${fn.toString()} ${opt.toString(2).padStart(12, '0').split('').join(' ')}`) } function printTree() { console.log(`┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ │ │ │ │ │ │ └─╸ is function │ │ │ │ │ │ │ │ │ │ └───╸ is never optimized │ │ │ │ │ │ │ │ │ └─────╸ is always optimized │ │ │ │ │ │ │ │ └───────╸ is maybe deoptimized │ │ │ │ │ │ │ └─────────╸ is optimized │ │ │ │ │ │ └───────────╸ is optimized by TurboFan │ │ │ │ │ └─────────────╸ is interpreted │ │ │ │ └───────────────╸ is marked for optimization │ │ │ └─────────────────╸ is marked for concurrent optimization │ │ └───────────────────╸ is optimizing concurrently │ └─────────────────────╸ is executing └───────────────────────╸ topmost frame is turbo fanned`) } let func1 let func2 let func3 await (async function () { return const fn1 = async () => await Promise.reject().catch(() => null) === null ? 1 : 0; const fn2 = async () => await Promise.reject().catch(() => {}) == null ? 1 : 0; const fn3 = async () => await Promise.reject().catch(() => null) == null ? 1 : 0; const noop = () => null; const fn4 = async () => await Promise.reject().catch(noop) == null ? 1 : 0; const fn5 = async () => await Promise.reject().catch(noop) === null ? 1 : 0; const fn6 = () => Promise.reject().catch(() => null).then(x => x === null ? 1 : 0); const fn7 = () => Promise.reject().catch(() => {}).then(x => x == null ? 1 : 0); const fn8 = () => Promise.reject().catch(() => null).then(x => x == null ? 1 : 0); const fn9 = () => Promise.reject().catch(noop).then(x => x == null ? 1 : 0); const fn10 = () => Promise.reject().catch(noop).then(x => x === null ? 1 : 0); func1 = [fn1, fn2, fn3, fn4, fn5, fn6, fn7, fn8, fn9, fn10]; for (let fun of func1) { %OptimizeFunctionOnNextCall(fun); } for (var i = 0; i < 100000; i++) { for (let fun of func1) { await fun() } } for (let fun of func1) { printCurrentStatus(fun); } printTree() summary(() => { bench('Null with ===', fn1); bench('Undefined with ==', fn2); bench('Null with ==', fn3); bench('Cached Null with ==', fn4); bench('Cached Null with ===', fn5); bench('[sync] Null with ===', fn6); bench('[sync] Undefined with ==', fn7); bench('[sync] Null with ==', fn8); bench('[sync] Cached Null with ==', fn9); bench('[sync] Cached Null with ===', fn10); }); }) await (async function () { const alt1 = function () { (Math.round(Math.random()) ? null : 1) ?? 0 }; const alt2 = function () { (Math.round(Math.random()) ? null : 1) || 0 }; const alt3 = function () { (Math.round(Math.random()) ? undefined : 1) ?? 0 }; const alt4 = function () { (Math.round(Math.random()) ? undefined : 1) || 0 }; let check = new Array(100).fill(0).map(() => Math.round(Math.random()) ? null : 1) let check2 = new Array(100).fill(0).map(() => Math.round(Math.random()) ? undefined : 1) const alt5 = function () { let out = 0; for (let x of check) { out += x ?? 0 } return out }; const alt6 = function () { let out = 0; for (let x of check) { out += x || 0 } return out }; const alt7 = function () { let out = 0; for (let x of check2) { out += x ?? 0 } return out }; const alt8 = function () { let out = 0; for (let x of check2) { out += x || 0 } return out }; func2 = [alt1, alt2, alt3, alt4, alt5, alt6, alt7, alt8]; for (let fun of func2) { %OptimizeFunctionOnNextCall(fun); } for (var i = 0; i < 100000; i++) { for (let fun of func2) { fun() } } for (let fun of func2) { printCurrentStatus(fun); } printTree() summary(() => { bench('null/1 ?? 0', alt1); bench('null/1 || 0', alt2); bench('undefined/1 ?? 0', alt3); bench('undefined/1 || 0', alt4); }); summary(() => { bench('arr null/1 ?? null', alt5); bench('arr null/1 || null', alt6); bench('arr und/1 ?? null', alt7); bench('arr und/1 || null', alt8); }); })() await (async function () { const alt1 = function () { let out = 0; for (let x = 0; x < 100; x++) { out += (Math.round(Math.random()) ? null : 1) ?? 0 } return out }; const alt2 = function () { let out = 0; for (let x = 0; x < 100; x++) { out += (Math.round(Math.random()) ? null : 1) || 0 } return out }; const alt3 = function () { let out = 0; for (let x = 0; x < 100; x++) { out += (Math.round(Math.random()) ? undefined : 1) ?? 0 } return out }; const alt4 = function () { let out = 0; for (let x = 0; x < 100; x++) { out += (Math.round(Math.random()) ? undefined : 1) || 0 } return out }; func3 = [alt1, alt2, alt3, alt4]; for (let fun of func3) { %OptimizeFunctionOnNextCall(fun); } for (var i = 0; i < 100000; i++) { for (let fun of func3) { fun() } } for (let fun of func3) { printCurrentStatus(fun); } printTree() summary(() => { bench('loop null/1 ?? 0', alt1); bench('loop null/1 || 0', alt2); bench('loop und/1 ?? 0', alt3); bench('loop und/1 || 0', alt4); }); })() // Start the benchmark run().then(() => { for (let fun of func3) { printCurrentStatus(fun); } printTree() });