简体   繁体   English

为什么封装的Javascript函数有这么大的性能差异?

[英]Why this huge performance difference for an encapsulated Javascript function?

So I have this simple code: 所以我有这个简单的代码:

function Run () {
  var n = 2*1e7;
  var inside = 0;
  while (n--) {
    if (Math.pow(Math.random(), 2) +
        Math.pow(Math.random(), 2) < 1)
      inside++;
  }

  return inside;
}

var start = Date.now();
Run();
console.log(Date.now() - start);

And it will output some time around 335ms. 它会输出大约335毫秒的时间。 That's pretty good. 那很不错。 But, if I encapsulate the Run function like this: 但是,如果我像这样封装Run函数:

var d = Date.now();
(function Run () {
  var n = 2*1e7;
  var inside = 0;
  while (n--) {
    if (Math.pow(Math.random(), 2) +
        Math.pow(Math.random(), 2) < 1)
      inside++;
  }

  return inside;
})();
console.log(Date.now() - d);

It will output 18319ms, which is much worse than the case before. 它将输出18319ms,这比以前的情况要糟糕得多。 Why is this ? 为什么是这样 ?

Also, if it matters, I'm running it on Chrome 26.0.1410.63, in the console. 此外,如果重要,我在控制台的Chrome 26.0.1410.63上运行它。 On node.js both snippets perform well on the console. 在node.js上,两个片段在控制台上都表现良好。

There is no difference with function decleration and function expressions WRT to optimization, that would be ridiculous. 函数解除和函数表达式WRT与优化没有区别,这将是荒谬的。


Console code in Google Chrome is wrapped in with statement like this: 谷歌浏览器控制台的代码被包裹在with这样的语句:

 with ((console && console._commandLineAPI) || {}) {
      //Your code is concatenated here
 }

Because function declarations are hoisted, the former code will be effectively this: 因为函数声明被挂起,所以前面的代码实际上是这样的:

function Run () {
  var n = 2*1e7;
  var inside = 0;
  while (n--) {
    if (Math.pow(Math.random(), 2) +
        Math.pow(Math.random(), 2) < 1)
      inside++;
  }

  return inside;
}

with ((console && console._commandLineAPI) || {}) {
  var start = Date.now();
  Run();
  console.log(Date.now() - start);
}

So the declaration is running outside with statement. 因此,声明之外运行with声明。 In fact it is not valid syntax to have function declaration in a block, function declaration can only be a top level statement . 实际上,在块中具有函数声明是无效的语法, 函数声明只能是顶级语句

So anyway because of historical reasons V8 is nice and hoists it out instead of throwing syntax error: 所以无论如何,由于历史原因V8很好,并提升它而不是抛出语法错误:

var i = 3;

with({i:4}) {
    function test() {
        console.log(i);
    }
}
test();//logs 3 so it is obviously **not** under `with` influence

So because the declaration is not under with statement, it will run much faster. 所以,因为该声明是没有根据with声明,它会运行得更快。 With statement is not optimizable* under V8 and also breaks lexical scoping. 声明在V8下不可优化*也会打破词法范围。


*Not optimizable means the optimizing compiler will not look at the code instead only the generic compiler will generate code for the function. *不可优化意味着优化编译器不会查看代码,只有通用编译器才会为函数生成代码。 It is comparable to firefox's interpreter vs JIT mode. 它与firefox的解释器和JIT模式相当。 If you wish to know more about what language features disable optimization in V8, read optimization killers 如果您想了解更多有关V8中禁用优化的语言功能的信息,请阅读优化杀手

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 封装在函数中的JavaScript事件监听器 - JavaScript Event Listener encapsulated in a function 为什么复杂循环和许多循环之间存在如此巨大的性能差异 - Why is there such a huge performance difference between complex loops and many loops Javascript Performance Huge页面 - Javascript Performance Huge page 确定封装的javascript函数参数的值 - Determine value of encapsulated javascript function parameters 设置私有变量以在封装的JavaScript函数中重用 - Set Private Variable for Reuse In Encapsulated JavaScript function 为什么不将正则表达式字符串封装在Javascript中的引号中? - Why are regular expression strings not encapsulated in quotes in Javascript? 为什么while和do ...之间的巨大时差在JavaScript中 - Why the huge time difference between while and do..while in JavaScript 函数初始化位置之间的性能差异[JavaScript] - Performance difference between function initialization locations [JavaScript] 为什么DOM读/写操作的微小重新排序会导致巨大的性能差异 - why a tiny reordering of DOM Read/Write operations causes a huge performance difference 循环对性能测量产生巨大影响 - Loop making a huge difference in performance measurement
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM