Javascript深层对象属性访问时间

时间:2017-10-26 14:21:38

标签: javascript

这是一个示例代码。基本上两个函数的不同之处在于将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;
&#13;
&#13;

有人可以解释为什么notPlain()功能比plain()更快?

修改 按照建议创建jsperf基准测试。 我想它与兑现和javascript引擎优化真的有关。将研究更多关于这一点。谢谢大家! https://jsperf.com/deep-property

3 个答案:

答案 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)

塔拉斯,没有惊喜。它实际上更慢(Chrome 61):

  • notPlain:22.6ms
  • plain:60.9ms

“notPlain”访问内存中的“atomic”元素。 “普通”必须遍历参考链。此外,V8可能必须检查是否没有getter,object属性等干扰相应的名称。因此它的速度较慢。