-
-
Save eth-p/1fa72e77bd03425f7225fe9a573dd37b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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