Skip to content

Instantly share code, notes, and snippets.

@eth-p
Forked from Llorx/evalFuncOpt.js
Created March 27, 2023 21:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eth-p/1fa72e77bd03425f7225fe9a573dd37b to your computer and use it in GitHub Desktop.
Save eth-p/1fa72e77bd03425f7225fe9a573dd37b to your computer and use it in GitHub Desktop.
/**
* Test V8 optimization against eval and new Function
* Run with: node --allow-natives-syntax evalFuncOpt.js
* More verbose with: node --trace_opt --trace_deopt --allow-natives-syntax evalFuncOpt.js
*
* More info at: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
*/
var b = 0;
function getStatus(fn) {
const flags = [];
const vs = %GetOptimizationStatus(fn);
if (vs & (1 << 0)) flags.push('kIsFunction');
if (vs & (1 << 1)) flags.push('kNeverOptimize');
if (vs & (1 << 2)) flags.push('kAlwaysOptimize');
if (vs & (1 << 3)) flags.push('kMaybeDeopted');
if (vs & (1 << 4)) flags.push('kOptimized');
if (vs & (1 << 5)) flags.push('kTurboFanned');
if (vs & (1 << 6)) flags.push('kInterpreted');
if (vs & (1 << 7)) flags.push('kMarkedForOptimization');
if (vs & (1 << 8)) flags.push('kMarkedForConcurrentOptimization');
if (vs & (1 << 9)) flags.push('kOptimizingConcurrently');
if (vs & (1 << 10)) flags.push('kIsExecuting');
if (vs & (1 << 11)) flags.push('kTopmostFrameIsTurboFanned');
if (vs & (1 << 12)) flags.push('kLiteMode');
if (vs & (1 << 13)) flags.push('kMarkedForDeoptimization');
if (vs & (1 << 14)) flags.push('kBaseline');
if (vs & (1 << 15)) flags.push('kTopmostFrameIsInterpreted');
if (vs & (1 << 16)) flags.push('kTopmostFrameIsBaseline');
return flags.join(', ');
}
const HOT_ITERS = 100_000_000;
function performTest(fn, desc) {
console.log(`\x1B[33m==> Testing Function: ${desc}\x1B[0m`);
// Warmup.
console.log("Before Call", getStatus(fn));
fn(0, 1);
fn(2, 3);
// Force optimization.
console.log("Before Optimization", getStatus(fn));
%OptimizeFunctionOnNextCall(fn);
fn(3, 4);
// Force hot loop optimization.
console.log("Before Hot", getStatus(fn));
for (let i = 0; i < HOT_ITERS; i++) fn(i, -i);
// After hot loop timization.
console.log("After Hot", getStatus(fn));
const start = performance.now();
for (let i = 0; i < HOT_ITERS; i++) fn(i, -i);
const end = performance.now();
console.log("Timings:", (end - start));
console.log();
}
function adder(a, b) {
return b%2 ? a + b : b%3 ? a - b : b%5 ? b / a : a * b;
}
const adderFCtor = new Function('a', 'b', 'return b%2 ? a + b : b%3 ? a - b : b%5 ? b / a : a * b');
const adderFEval = eval('(a, b) => { return b%2 ? a + b : b%3 ? a - b : b%5 ? b / a : a * b; }');
performTest(adder, "Source");
performTest(adder, "new Function");
performTest(adder, "eval");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment