15

我有一个存储为字符串的值,我知道它总是一个整数。但我需要它作为一个数字,所以我在做n = n * 1. 然后我想“嗯,我可能应该只使用parseInt(). 然后我运行了一些 jsperf 测试,Firefox 中的结果很有趣:

http://jsperf.com/parseintx1

总的来说,操作看起来非常相似,除了在 Firefox 中,使用*1速度非常快。这里发生了什么?


编辑

有人进行了以 10 为基础的测试,并整体更新了测试。点击这个也可以提供一些额外的反馈:http: //jsperf.com/parseintx1/2

4

2 回答 2

2

无论如何,我都不是 JavaScript 引擎专家,甚至不是编译器专家,但我很确定这归结为编译器可以告诉这个事实:

var a = "123";
a = a * 1;

真的完全一样:

var a = 123;

因为“a”是一个局部变量,并且从它的初始化点到那个* 1表达式都是未使用的,所以根本没有必要生成代码来执行操作。在那之后,编译器也可能会说“a”不可能从函数中“逃脱”,所以真的没有任何意义;也就是说,* 1测试的结果可能与您得到的结果相同:

function() {}

但是,在这种parseInt()情况下,编译器无法确定它parseInt()是真的parseInt(),因为它可能已被重新定义。因此,它必须生成代码来进行函数调用。

于 2012-08-28T17:30:06.427 回答
2

它必须是测试设置,因为这个版本在 Firefox 中也给出了预期的结果。我认为,在您的设置中,它parseInt在每次迭代中应用于每个变量(嗯,至少在 FF 中),而从Stringto的转换Number可以应用于乘法测试中的第一次迭代,之后变量是数字乘法不再需要转换。

在版本 7 中,变量在测试设置中分配,并且测试在每次迭代时分配新变量。现在两个测试都有“相等的变化”,并且parseInt优于乘法测试。

在检查 IE[8,9] 中的测试并看到它的结果看起来像 FF 之后,我认为 Chrome 结果有一个解释:我很确定 Chrome/Webkit 在测试的第一个版本中有更好的优化(尤其是parseInt部分),这会给那里带来更好的结果parseInt。它可能是那些浏览器中使用的V8引擎中代码(部分)的预编译。

于 2012-08-28T17:30:18.760 回答