为什么重复子对象导航比使用简写变量更快?
Why is repeated sub-object navigation faster than using a short-hand variable?
对不起,我不知道如何正确地表达这个问题,但问题是:
var o = {
my: {
very: {
deep: {
sub: {
fn(x) {
return x + 1;
}
}
}
}
}
};
var n = 0;
//without short-hand function
var timeStart = performance.now();
for (var i = 0; i < 5000000; i++) {
n += o.my.very.deep.sub.fn(i);
}
var timeEnd = performance.now();
console.log(timeEnd - timeStart);
n = 0;
//with short-hand function
var fn = o.my.very.deep.sub.fn;
timeStart = performance.now();
for (var i = 0; i < 5000000; i++) {
n += fn(i);
}
timeEnd = performance.now();
console.log(timeEnd - timeStart);
问题是:为什么第一个循环中的代码快了5-7%(当在全局作用域中执行时),尽管它必须重复地向下执行子对象,而在第二个循环中,它使用简写的fn
代替?
PS:如果你发现一个更好的题目,请随意编辑。
var o = {
my: {
very: {
deep: {
sub: {
fn(x) {
return x + 1;
}
}
}
}
}
};
var n = 0;
//without short-hand function
var timeStart = performance.now();;
for (var i = 0; i < 5000000; i++) {
n += o.my.very.deep.sub.fn(i);
}
var timeEnd = performance.now();;
console.log(timeEnd - timeStart);
n = 0;
//with short-hand function
var fn = o.my.very.deep.sub.fn;
timeStart = performance.now();
for (var i = 0; i < 5000000; i++) {
n += fn(i);
}
timeEnd = performance.now();
console.log(timeEnd - timeStart);
运行这个(注意使用performance.now()
而不是Date
),两者之间的差异似乎非常小。在一些运行中,第一个实现将(非常非常轻微地)领先,在一些运行中则是后者。如果没有一个独立的测试环境,它可能是最好的,但是,从本质上讲,这个级别的测试将向您显示,这两种方法之间几乎没有区别。
第二个更快,因为您不需要在每次迭代中进行属性查找。
在第一个中,你说go to 0然后my然后very然后deep然后sub然后每次迭代执行函数o.my.very.deep.sub.fn(i)
但在第二个你缓存fn
与var fn = o.my.very.deep.sub.fn;
在顶部现在它不需要做查找fn
在每次迭代,避免额外的工作
像v8这样的引擎为优化做了内联缓存,它们甚至可能不会为每次迭代做动态查找,但这完全取决于实现。检查这个以了解v8是如何实现它的。快速属性访问也是v8优化属性访问的方式,但要点是
V8通常对你的代码非常乐观,并试图提高速度尽量往上爬。但有时它所做的假设无效(隐藏类不是预期的)。在这种情况下,V8将用完全未优化的代码替换内联缓存快速路径代码代码。
相关文章:
- 替换另一个变量对象中的变量值
- 如何从表单变量对象中获取特定的from属性
- 变量/对象是否按值传递,为什么我不能在 javascript 中使用变量更改对象的属性
- 执行上下文和变量对象在 JavaScript 中实际上是一回事吗?
- 如何将变量对象传递到多个javascript弹出窗体
- 如何将javascript变量/对象从一个页面传递到另一个页面
- 在具有递增的变量/对象中存储和控制传单 GeoJSON 图层
- 在回调中重用变量/对象
- 给一个有1个变量/对象的函数给定几个参数
- 使用单词'英语'因为变量/对象名称在javascript中不起作用
- 如何访问变量对象中的数据
- 使用onclick调用变量对象中的函数
- 使用Underscore JS部分和for循环的未定义变量对象
- 如何查看我的变量对象
- 变量对象属性名称作为javascript中的参数
- 从变量对象中移除DOM元素,以便将其发布到服务器
- 根据变量对象是否等于“true”输出内容
- 如何连接(变量+对象键名)以获得点表示法的对象值
- 为什么在ES5中将变量对象改为词法环境
- 动态引用变量(对象)