Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用临时变量代替重复的完整引用是否更好?_Javascript_Performance_Object - Fatal编程技术网

Javascript 使用临时变量代替重复的完整引用是否更好?

Javascript 使用临时变量代替重复的完整引用是否更好?,javascript,performance,object,Javascript,Performance,Object,假设我们有一个类似于: var foo = { a: { b: { c: { d: { e: { f: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] } } } } } }; 我们希望在函数中使用对象的各个部分,如下所示: function doStuff() { if ( foo.a.b.c.d.e.f[ 5 ] >= some_important_filter_value ) { alert( "Some important filter

假设我们有一个类似于:

var foo = { a: { b: { c: { d: { e: { f: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] } } } } } };
我们希望在函数中使用对象的各个部分,如下所示:

function doStuff() {
    if ( foo.a.b.c.d.e.f[ 5 ] >= some_important_filter_value ) {
        alert( "Some important filter value is " + foo.a.b.c.d.e.f[ 5 ] +
            "!!\nRun for your lives!!" );
    }
}
为了参数起见,
foo
中包含的值在函数执行过程中不会改变,或者说,通常不会改变

从对象读取值并将其存储为临时变量/常量更好,还是完全可以使用对象的完整路径
foo
作为值的参考?

i、 e.是

“更好”,如果是,具体以什么方式

我自己在Google Chrome的JS控制台上进行的有限测试显示
100000
在深入查询对象时,与查询临时变量以大致相同速度运行的相同数量的循环相比

有效地将
foo
中的值复制并存储到临时变量中以供多次使用,在某些情况下可能具有实用价值,因为代码/文件大小可能会减小,可读性可能会提高,但出于本问题的目的,请将其放在一边,还有哪些支持它的论点

对于现代JS解释器来说,创建和处理临时变量肯定比直接引用对象中的值要简单得多

为什么以及如何将
var temp=foo.a.b.c.
优于跳过定义,仅通过我们已有的引用使用值?


我想基本上我要问的是-我的引用中有多少点真的很重要吗,因为从长远来看,它只是一个引用-或者是吗?

正如您自己测试的那样,正如上面Matt Burland所确认的,嵌套对象引用在性能上与复制的引用没有明显的不同


在性能方面,您需要注意的是函数调用。如果您有foo.a().b().c()。。。相反,函数调用本身开始变得昂贵。在这里,差异变得明显,正如我对Matt的jsperf测试所做的小修改所示:

在学究式的奇妙领域中,你将一次又一次地为解决这些引用而付出代价

如果这些是“类”(构造的对象,它可能引用proto链上的值),那么您需要支付额外的惩罚,即无法在对象上找到值,并将proto链升序,直到找到为止(或单击Object.prototype,当您尝试访问缺少的对象的属性时,仍会丢失该属性,并引发引用错误)

总而言之,如果你的现代发动机压力测试增加了1毫秒,我会大吃一惊

Chrome的V8将在动态重新编译代码方面发挥很大作用,其中包括展开循环、内联函数等;只要每次都一致地使用函数(传递类似的参数/参数类型)

我相信,大约在2012年左右,关于用Chrome编写游戏引擎,有一些很好的讨论

寓意是,如果你做了几次以上,你所做的大部分事情都会被编译成一个内联操作

…在新浏览器中

当你做了这样的事情时,你会受到表演上的打击

if (i % 3001) { a.b.e.f.g[6]; }
else { a.b.c.d.e.f[5]; }
…同样,这是现代发动机

如果您要在运行IE6的2003 Windows XP系统上运行负载测试,由于上述原因,您的数字应该不同

它们不应该有几百毫秒的间隔…
但是,它们应该多次反映解引用值的性能影响,如果属性链接到proto,则性能损失应该增加,并根据链上的距离再次增加,以解析每个属性


换句话说,我指的是那些浏览器,
a.b.c
a[“b”][“c”]
的测试在视觉上是不同的。

“我的参考中有多少个点真的很重要吗,因为从长远来看,这只是一个参考”不。在某种程度上,一种方法会更“有效”相比于另一个,但最终在执行上的差异将是如此之小,以至于与此无关。看起来可读性和代码维护是另一个因素,除非您分析代码并发现它是一个瓶颈,否则我不会担心它。另一方面,可读性是一个更大的问题,因此复制
foo。a、 b.c.
当您要多次引用临时变量时,将其放入临时变量可能是一个好主意。这也会使您更难一次意外地键入和访问
foo.a.b.c
以及下一次访问
foo.a.c.b
。“我自己的有限测试”:如果你好奇的话,你也可以试试。这是我设置的一个测试:,几乎没有区别。这可以归结为“错误伤害更大…”,但错误总是有害的,是的,正是现代编译器/解释器的效率让我首先提出了这个问题。如果这是二十世纪初,我将毫不怀疑局部/临时变量是“理想的”,但它现在是未来,到处都有大量的一次性变量似乎完全没有必要。我继续怀疑它是否有比看上去更多的地方。@FredGandt:编译器优化了您的开销,这不是编写糟糕代码的借口。在这种特殊情况下,重复长时间的属性访问不是干巴巴的。@FredGandt如果您阅读它的话。@FredGandt当然,你应该注意到,爬上原型链不是一个“错误”,而是语言的一个特性。此外,这不是一个在编译代码中犯“错误”的问题;传递一个数字,而不是传递一个数字的字符串表示,或者传递一个特定类型的对象实例,然后传入一个in
if (i % 3001) { a.b.e.f.g[6]; }
else { a.b.c.d.e.f[5]; }