我有一个存储为字符串的值,我知道它总是一个整数。但我需要它作为一个数字,所以我在做n = n * 1
. 然后我想“嗯,我可能应该只使用parseInt()
. 然后我运行了一些 jsperf 测试,Firefox 中的结果很有趣:
总的来说,操作看起来非常相似,除了在 Firefox 中,使用*1
速度非常快。这里发生了什么?
编辑
有人进行了以 10 为基础的测试,并整体更新了测试。点击这个也可以提供一些额外的反馈:http: //jsperf.com/parseintx1/2
我有一个存储为字符串的值,我知道它总是一个整数。但我需要它作为一个数字,所以我在做n = n * 1
. 然后我想“嗯,我可能应该只使用parseInt()
. 然后我运行了一些 jsperf 测试,Firefox 中的结果很有趣:
总的来说,操作看起来非常相似,除了在 Firefox 中,使用*1
速度非常快。这里发生了什么?
编辑
有人进行了以 10 为基础的测试,并整体更新了测试。点击这个也可以提供一些额外的反馈:http: //jsperf.com/parseintx1/2
无论如何,我都不是 JavaScript 引擎专家,甚至不是编译器专家,但我很确定这归结为编译器可以告诉这个事实:
var a = "123";
a = a * 1;
真的完全一样:
var a = 123;
因为“a”是一个局部变量,并且从它的初始化点到那个* 1
表达式都是未使用的,所以根本没有必要生成代码来执行操作。在那之后,编译器也可能会说“a”不可能从函数中“逃脱”,所以真的没有任何意义;也就是说,* 1
测试的结果可能与您得到的结果相同:
function() {}
但是,在这种parseInt()
情况下,编译器无法确定它parseInt()
是真的parseInt()
,因为它可能已被重新定义。因此,它必须生成代码来进行函数调用。
它必须是测试设置,因为这个版本在 Firefox 中也给出了预期的结果。我认为,在您的设置中,它parseInt
在每次迭代中应用于每个变量(嗯,至少在 FF 中),而从String
to的转换Number
可以应用于乘法测试中的第一次迭代,之后变量是数字乘法不再需要转换。
在版本 7 中,变量在测试设置中分配,并且测试在每次迭代时分配新变量。现在两个测试都有“相等的变化”,并且parseInt
优于乘法测试。
在检查 IE[8,9] 中的测试并看到它的结果看起来像 FF 之后,我认为 Chrome 结果有一个解释:我很确定 Chrome/Webkit 在测试的第一个版本中有更好的优化(尤其是parseInt
部分),这会给那里带来更好的结果parseInt
。它可能是那些浏览器中使用的V8引擎中代码(部分)的预编译。