V8常见去优化原因一览

原作者:江凌

V8 bailout reasons

v8 bailout reasons 的例子, 解释和建议. 帮助alinode的用户根据 CPU-Profiler 的提示进行优化。

索引

Bailout reasons

Bailout reasons

Assignment to parameter in arguments object

  • 简单例子
// sloppy mode only
function test(a) {
  if (arguments.length < 2) {
    a = 0;
  }
}
  • Why

    • 只会在函数中重新赋值参数发生。
  • Advices

    • 你不能给变量 a 重新赋值.
    • 最好使用 strict mode .
    • V8 最新的 TurboFan 会有优化 #1.

Bad value context for arguments value

  • 简单例子
// strict & sloppy modes
function test1() {
  arguments[0] = 0;
}

// strict & sloppy modes
function test2() {
  arguments.length = 0;
}

// strict & sloppy modes
function test3() {
  return arguments;
}

// strict & sloppy modes
function test4() {
  var args = [].slice.call(arguments);
}

// strict & sloppy modes
function test5() {
  var a = arguments;
  return function() {
    return a;
  };
}

ForInStatement with non-local each variable

  • 简单例子
// strict & sloppy modes
function test1() {
  var obj = {};
  for(key in obj);
}

// strict & sloppy modes
function key() {
  return 'a';
}
function test2() {
  var obj = {};
  for(key() in obj);
}

Object literal with complex property

  • 简单例子
// strict & sloppy modes
function test() {
  return {
    __proto__: 3
  };
}
  • Why
  • Advices

    • 简化 Object。

ForInStatement is not fast case

  • 简单例子
for (var prop in obj) {
  /* lots of code */
}
  • Why

    • for 循环中包含太多的代码。
  • Advices

    • for 循环中的提取代码提取为函数。

Reference to a variable which requires dynamic lookup

  • 简单例子
// sloppy mode only
function test() {
  with ({x:1}) {
    return x;
  }
}
  • Why

    • 编译时编译定位失败,Crankshaft需要重新动态查找。#3
  • Advices

    • TurboFan可以优化。

TryCatchStatement

  • 简单例子
// strict & sloppy modes OR // sloppy mode only
function func() {
  return 3;
  try {} catch(e) {}
}
  • Why

    • try/catch 使得控制流不稳定,很难在运行时优化。
  • Advices

    • 不要在负载重的函数中使用try/catch.
    • 可以重构为 try { func() } catch

TryFinallyStatement

  • 简单例子
// strict & sloppy modes OR // sloppy mode only
function func() {
  return 3;
  try {} finally {}
}

Unsupported phi use of arguments

  • 简单例子
// strict & sloppy modes
function test1() {
  var _arguments = arguments;
  if (0 === 0) { // anything evaluating to true, except a number or `true`
    _arguments = [0]; // Unsupported phi use of arguments
  }
}

// strict & sloppy modes
function test2() {
  var _arguments = arguments;
  for (var i = 0; i < 1; i++) {
    _arguments = [0]; // Unsupported phi use of arguments
  }
}

// strict & sloppy modes
function test3() {
  var _arguments = arguments;
  var again = true;
  while (again) {
    _arguments = [0]; // Unsupported phi use of arguments
    again = false;
  }
}
  • Why

    • Crankshaft 无法知道 _arguments是 object 或 array.
    • 深入了解
  • Advices

    • 最好操作 arguments 的拷贝.
    • TurboFan 可以优化 #1.

Yield

  • 简单例子
// strict & sloppy modes
function* test() {
  yield 0;
}

Resources

上一篇:Timer 源码解读[连载2]


下一篇:实现按行读取文件,把内容按照第三种内存模型打包数据传出,把行数通过函数参数传出。