这是一个示例代码。基本上两个函数的不同之处在于将n
上的值赋值/不赋值给变量。
let a = { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 10 } } } } } } } } } } } } };
function notPlain() {
console.time('notPlain');
let sum = 0;
const number = a.b.c.d.e.f.g.h.i.j.k.l.m.n;
for (let i = 0; i < 10000000; i++) {
sum += number;
}
console.timeEnd('notPlain');
}
function plain() {
console.time('plain');
let sum = 0;
for (let i = 0; i < 10000000; i++) {
sum += a.b.c.d.e.f.g.h.i.j.k.l.m.n;
}
console.timeEnd('plain');
}
notPlain();
plain();
&#13;
有人可以解释为什么notPlain()
功能比plain()
更快?
修改
按照建议创建jsperf
基准测试。
我想它与兑现和javascript引擎优化真的有关。将研究更多关于这一点。谢谢大家!
https://jsperf.com/deep-property
答案 0 :(得分:3)
Plain使用了很多引用(每次内部对象都需要在每次更改的情况下进行检查),这似乎做了很多。 Not plain使用对int的单个引用,可以轻松优化。
答案 1 :(得分:0)
notPlain()
比plain()
快,因为每次循环时,plain()
必须评估表达式a.b.c.d.e.f.g.h.i.j.k.l.m.n
,(其中a
是全局变量)notPlain()
必须评估更简单的表达式number
(本地const
符号查找)。毫不奇怪,后者是一个更快的操作。
注意:以下内容回答了原始问题,该问题询问plain()
为什么比nonPlain()
更快。
您的代码产生了误导性结果,因为它是一种衡量效果的糟糕方式。基准测试Javascript是一项棘手的业务。即时编译器,热身和更多因素进入时机。尝试使用适当的性能测试框架,而不是像您一样的简单测试。您会发现notPlain()
会击败plain()
。
当我在节点中运行代码时,第一次,plain()
时钟为10.461毫秒,notPlain()
为10.050毫秒(因此,与您的结果相反,notPlain()
是大约快4%)。对这两种方法的第二组调用的notPlain()
为7.176 ms,plain()
为8.374 ms(因此现在notPlain()
的速度提高了约14%)。不幸的是,这次测试的重复运行表明时间存在很大差异(尽管notPlain()
始终优于plain()
),因此在节点中运行也不是一个好的测试。
使用像jsperf这样的代码来测试这样的代码。
答案 2 :(得分:-1)
“notPlain”访问内存中的“atomic”元素。 “普通”必须遍历参考链。此外,V8可能必须检查是否没有getter,object属性等干扰相应的名称。因此它的速度较慢。