搞js的人都知道,Array.forEach比for loop要慢,很多情况下都是慢一倍左右,今天好奇为什么会慢,因为完全可以JIT的时候展开为一个for loop的。

于是翻了一下v8源代码,发现

if (!IS_UNDEFINED(current) || i in array) {

在执行callback之前会判断这个元素是否为undefined,而且用了双保险的方法,真是这个i in array导致了性能的大幅度衰减,不过这也是为了符合MDN上关于Array.forEach代码的行为规范

It is not invoked for indexes which have been deleted or which have been initialized to undefined.

不过又找到一个很有意思的jsperf结果,某些库如Lo-Dash的foreach居然比for loop还要快!

于是果断去翻了一下它的代码,发现它其实唯一的区别就是用的while loop

于是又翻了一个jsperf结果,虽然上面显示的现有测速结果是差不多,但我用自己的Chrome 28.0.1500测,是有30%左右的性能差别的,while loop要更快一些。还是很有意思的一件事~

Update: @zyxar 同学提到,是因为Lo-Dash提前分配了Array,然后提供了一个证明的jsperf。我也创建了另一个jsperf,在不保存结果的情况下,for-loop是最快的,但Lo-Dash的性能也只差一点。