首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >javascript V8优化和“泄漏参数”

javascript V8优化和“泄漏参数”
EN

Stack Overflow用户
提问于 2015-05-14 10:23:33
回答 2查看 1.4K关注 0票数 4

我在各地中读到,谨慎对待arguments对象是明智的,这是可以的.

代码语言:javascript
复制
    var i = arguments.length, args = new Array(i);
    while (i--) args[i] = arguments[i];

但是,这样行吗?

代码语言:javascript
复制
function makeArray (l) {
    var i = l.length, array = new Array(i);
    while (i--) array[i] = l[i];
    return array;
};
//...
//EDIT: put the function on an object to better represent the actual case
var o = {};
o.f = function (callback) {
    var args = makeArray (arguments);
    callback.apply(args[0] = this, args);
};

什么是“泄露论点”,它如何影响优化?

我关注的是V8,但我认为它也适用于其他编译器?

为了证明它有效..。

代码语言:javascript
复制
function makeArray (l) {
    var i = l.length, array = new Array(i);
    while (i--) array[i] = l[i];
    return array;
};
//...
//EDIT: put the function on an object to better represent the actual case
var o = {};
o.f = function (callback) {
    var args = makeArray (arguments);
    callback.apply(args[0] = this, args);
};
o.m = "Hello, ";
function test(f, n) {
    alert(this.m + " " + n)
}
o.f(test, "it works...")

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-14 12:15:59

arguments的问题与本地evalwith的问题相同:它们会导致混叠。因此,即使启用了这类函数的优化,也可能会浪费时间,这是JIT的一个问题,因为在编译器中花费的时间不是运行代码的时间(尽管优化过程中的一些步骤可以并行运行)。

由于arguments泄漏而产生的别名:

代码语言:javascript
复制
function bar(array) {    
    array[0] = 2;
}

function foo(a) {
    a = 1;
    bar(arguments);
    // logs 2 even though a is local variable assigned to 1
    console.log(a);
}
foo(1);

请注意,严格模式消除了这种情况:

代码语言:javascript
复制
function bar(array) {    
    array[0] = 2;
}

function foo(a) {
    "use strict";
    a = 1;
    bar(arguments);
    // logs 1 as it should
    console.log(a);
}
foo(1);

但是,严格模式也没有优化,我也不知道任何合理的解释,只是基准没有使用严格模式,而且很少使用严格模式。这可能会改变,因为许多es6特性需要严格的模式,otoh arguments在es6中不需要,所以.

票数 9
EN

Stack Overflow用户

发布于 2015-05-14 10:45:48

这是一个两方面的问题:

  1. 您将丢失任何和所有可能的优化和分支预测。 arguments对象是不可预测的。
  2. 你漏了记忆。真的很糟!

考虑以下代码(冒着自己的风险运行它!):

代码语言:javascript
复制
function a(){return arguments;}

x=a(document.getElementsByTagName('*'));

window._interval=setInterval(function(){

    for(var i=0;i<1e6;i++)
    {
        x=a(x);
    }
},5000);
代码语言:javascript
复制
*{font-family:sans-serif;}
代码语言:javascript
复制
<p>Warning! This may overheat your cpu and crash your browser really badly!</p>

<p>I'm not responsible for any software and hardware damages!</p>

<p><b>Run at your own risk!!!</b></p>

<p>If you ran this code, press F5 to stop or close the browser.</p>

<p>If you want, you can try to <button onclick="window.clearInterval(window._interval);window.x='';">stop it</button>. (the RAM may remain unchanged)</p>

现在,当您运行RAM时,请注意内存的增加(它以每5秒300至500 up的速度增长)。

简单地传递参数的天真实现可能会导致这些问题。

更不用说,您的代码(通常)会稍微慢一点。

请注意这一点:

代码语言:javascript
复制
function a(){return arguments;}
function b(arg){return arg;}

x=a(document.getElementsByTagName('*'));

window._interval=setInterval(function(){

    for(var i=0;i<1e6;i++)
    {
        x=b(x);
    }
},5000);
代码语言:javascript
复制
*{font-family:sans-serif;}
代码语言:javascript
复制
<p>This may be safe, but be careful!</p>

<p>I'm not responsible for any software and hardware damages!</p>

<p><b>Run at your own risk!!!</b></p>

<p>If you ran this code, press F5 to stop or close the browser.</p>

<p>If you want, you can try to <button onclick="window.clearInterval(window._interval);window.x='';">stop it</button>.</p>

不会产生和之前的代码相同的效果。

这是因为b()返回相同的变量,而不是对新的arguments对象的新引用。

这是非常的一个重要区别。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30234908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档