我知道像String(1234)和Number("1234")这样的类型转换更干净、更好,但我只是尝试对其他方法进行基准测试,特别是"" + 1234 // -> "1234"和- - "1234" // -> 1234。
结果(对我来说)相当令人吃惊。我在Chrome中遍历了100,000,000次。
我用了这个简单的代码。
var then = Date.now();
for (var i = 0; i < 100000000; ++i) {
var a = - - "1234";
};
console.log(Date.now() - then);Number("1234")为2351 ms,- - "1234"为748 ms。
与此类似,String(1234)的频率为3701 ms,而"" + 1234仅为893 ms。
两者之间的差别令人惊讶地巨大。
我的问题是:是什么使显式的投射比隐含的要慢得多?我的直觉告诉我它应该是相反的。
使用隐式铸造是一种良好的实践吗?尤其是讨厌的- - "1234"?有没有更好的选择?
PS:我刚刚在Firefox上尝试了同样的方法。它大约慢了500倍(但隐式转换仍然要快得多)。怎么一回事?它与分支预测或类似的东西有关吗?我想我的标杆是错的。
发布于 2016-06-05 22:54:47
如果您不使用常量,如果使用i瞬间,则结果将完全不同:
console.time('a');
for (var i = 0; i < 1e7; ++i) {
var a = String(i);
};
console.timeEnd('a');
console.time('b');
for (var i = 0; i < 1e7; ++i) {
var a = "" + i;
};
console.timeEnd('b');输出:
a: 1062.192ms
b: 884.535ms注意,我也必须移除10的幂。100000000 === 1e8和我使用1e7。
这表明,在使用常量时,就像在基准测试中一样,在引擎盖下出现了很多优化。
现在,Number(...)看起来更快了:
console.time('a');
for (var i = 0; i < 1e7; ++i) {
var a = - - ("" + i);
};
console.timeEnd('a');
console.time('b');
for (var i = 0; i < 1e7; ++i) {
var a = Number("" + i);
};
console.timeEnd('b');输出:
a: 2010.903ms
b: 1557.735ms发布于 2016-06-05 22:58:48
理论上,使用一元+和-运算符应该比调用Number和String更快,因为它们使用内部ToNumber和ToString方法将操作数转换为number Type,而Number和String则需要函数调用的额外开销。
然而,理论并不总是与实践相匹配,因为优化Number(x)到+x可能非常简单,反之亦然,编译器认为这样做更快。
是什么使显式投射比隐含的要慢得多?我的直觉告诉我它应该是相反的。
与往常一样,在特定版本的浏览器中获得的结果不一定适用于其他浏览器,甚至不一定适用于同一浏览器的其他版本。理论上,显式转换应该更慢,但我不会依赖于跨实现的转换。
使用隐式铸造是一种良好的实践吗?尤其是那些"1234"?有没有更好的选择?
这应该是-'1234',我会说“不”,因为-操作符将它的参数转换为数字,因此永远不需要编写x - -y。
与加法运算符+一起使用一元+进行转换更为常见,在大多数情况下编写+x或Number(x)也同样清楚。因此,请使用:
x + +y省去打字吧。
https://stackoverflow.com/questions/37647450
复制相似问题