Undefined variable vs Undefined 属性 令人困惑的表现
Undefined variable vs Undefined property perplexing performance
我在做一些基准测试,发现了一些我似乎无法解释的荒谬结果。
const a = undefined;
const b = {};
// add tests
suite
.add('Undefined variable', function () {
if(a > 0){
return true;
}
else{
return false;
}
})
.add('Undefined property', function () {
if(b.a > 0) {
return true;
}
else{
return false;
}
})
测试结果:
Undefined variable x 69,660,401 ops/sec ±2.48% (36 runs sampled)
Undefined property x 994,939,175 ops/sec ±0.85% (40 runs sampled)
Test Results
--------------------------------------------------------------------------
Undefined property : 994939174.67 ops/sec (+1328.27 %)
Undefined variable : 69660400.51 ops/sec ( +0.00 %)
--------------------------------------------------------------------------
有人知道为什么第一种情况 Undefined variable
比另一种慢很多吗?
我在 jsbench 测试中发现了类似的性能结果:https://jsbench.me/vdku4ert4l/2
(此处为 V8 开发人员。)
比较undefined > 0
总是有相同的性能。这里的区别在于,在您的一种情况下,V8 可以优化比较:对于像 b.a
这样的 属性 访问,它会记住所见对象的隐藏 class(即 b
的值);这就是称为“内联缓存”的技术的关键思想。
V8 将这个想法更进一步:如果所有遇到的对象都具有相同的隐藏 class,并且隐藏的 class 没有 a
属性 ,然后当该函数得到优化时,V8 会考虑该经验并生成优化的代码,该代码假设将来仍会如此,在这种情况下,它能够不断地折叠 属性 负载和比较。换句话说,它将函数优化为:
function undefined_property_optimized() {
(if b.__hidden_class__ !== kPreviousHiddenClass) Deoptimize;
return false;
}
其中 Deoptimize
表示:丢弃此优化代码并返回此函数的未优化代码(当然是在正确的点恢复执行)。
the first test Undefined variable
is being heavily slowed down
不,它根本没有减速。 other 案例可以说是“作弊”。
adding const b = { a: undefined };
doesn't change anything
这实际上在很大程度上取决于您 运行 测试的准确程度。在本地测试中,对我强制引擎执行的操作进行了微小的修改,这个添加要么没有效果,要么使两个函数具有相同的速度。
经验法则 #1:当你 运行 一个微基准测试并且你看到每秒有几亿次操作时,优化编译器能够优化几乎所有的东西,而你正在测试一个空的(或微不足道的)功能。
经验法则 #2:微基准测试的结果很难正确解释。您可能认为您在这里测量 属性 负载,或者 > 0
比较;这两个假设都是不正确的:在更快的情况下,没有加载属性,也没有执行 > 0
比较。要理解微基准测试,您确实需要研究生成的机器代码(and/or 其他引擎内部),以确保它正在测试您认为正在测试的内容。
经验法则 #3:现代高性能 JavaScript 引擎是非常复杂的野兽,相同的 JS 片段 不会 总是具有相同的性能;它在很大程度上取决于它周围的代码(周围的行和应用中其他地方的远处代码都会影响它)。
经验法则 #4:微基准测试的结果几乎不会转移到实际代码中——主要是因为以上三个规则:-)
旁注:当您发现自己写作时:
if (some_condition) {
return true;
} else {
return false;
}
那么你可以用 return some_condition
替换它。可能不会更快,但会使您的代码更短。
我在做一些基准测试,发现了一些我似乎无法解释的荒谬结果。
const a = undefined;
const b = {};
// add tests
suite
.add('Undefined variable', function () {
if(a > 0){
return true;
}
else{
return false;
}
})
.add('Undefined property', function () {
if(b.a > 0) {
return true;
}
else{
return false;
}
})
测试结果:
Undefined variable x 69,660,401 ops/sec ±2.48% (36 runs sampled)
Undefined property x 994,939,175 ops/sec ±0.85% (40 runs sampled)
Test Results
--------------------------------------------------------------------------
Undefined property : 994939174.67 ops/sec (+1328.27 %)
Undefined variable : 69660400.51 ops/sec ( +0.00 %)
--------------------------------------------------------------------------
有人知道为什么第一种情况 Undefined variable
比另一种慢很多吗?
我在 jsbench 测试中发现了类似的性能结果:https://jsbench.me/vdku4ert4l/2
(此处为 V8 开发人员。)
比较undefined > 0
总是有相同的性能。这里的区别在于,在您的一种情况下,V8 可以优化比较:对于像 b.a
这样的 属性 访问,它会记住所见对象的隐藏 class(即 b
的值);这就是称为“内联缓存”的技术的关键思想。
V8 将这个想法更进一步:如果所有遇到的对象都具有相同的隐藏 class,并且隐藏的 class 没有 a
属性 ,然后当该函数得到优化时,V8 会考虑该经验并生成优化的代码,该代码假设将来仍会如此,在这种情况下,它能够不断地折叠 属性 负载和比较。换句话说,它将函数优化为:
function undefined_property_optimized() {
(if b.__hidden_class__ !== kPreviousHiddenClass) Deoptimize;
return false;
}
其中 Deoptimize
表示:丢弃此优化代码并返回此函数的未优化代码(当然是在正确的点恢复执行)。
the first test
Undefined variable
is being heavily slowed down
不,它根本没有减速。 other 案例可以说是“作弊”。
adding
const b = { a: undefined };
doesn't change anything
这实际上在很大程度上取决于您 运行 测试的准确程度。在本地测试中,对我强制引擎执行的操作进行了微小的修改,这个添加要么没有效果,要么使两个函数具有相同的速度。
经验法则 #1:当你 运行 一个微基准测试并且你看到每秒有几亿次操作时,优化编译器能够优化几乎所有的东西,而你正在测试一个空的(或微不足道的)功能。
经验法则 #2:微基准测试的结果很难正确解释。您可能认为您在这里测量 属性 负载,或者 > 0
比较;这两个假设都是不正确的:在更快的情况下,没有加载属性,也没有执行 > 0
比较。要理解微基准测试,您确实需要研究生成的机器代码(and/or 其他引擎内部),以确保它正在测试您认为正在测试的内容。
经验法则 #3:现代高性能 JavaScript 引擎是非常复杂的野兽,相同的 JS 片段 不会 总是具有相同的性能;它在很大程度上取决于它周围的代码(周围的行和应用中其他地方的远处代码都会影响它)。
经验法则 #4:微基准测试的结果几乎不会转移到实际代码中——主要是因为以上三个规则:-)
旁注:当您发现自己写作时:
if (some_condition) {
return true;
} else {
return false;
}
那么你可以用 return some_condition
替换它。可能不会更快,但会使您的代码更短。