我在不同的节点版本中运行此测试:

function test() {
    var i;
    var bigArray = {};

    var start = new Date().getTime();

    for (i=0; i<100000; i+=1) {
        bigArray[i] = {};
        var j= Math.floor(Math.random() * 10000000);
        bigArray[i]["a" + j] = i.toString(32);
        if (i % 1000 === 0) console.log(i);
    }

    var end = new Date().getTime();
    var time = end - start;
    console.log('Execution time: ' + time);
}

test();

如您所见,它仅创建一个具有100000个字段的对象,其中每个字段只是一个只有一个字段的对象。此内部对象的键被强制为字母数字(如果键为数字,则执行正常)。

当我在不同的javascript实现/版本中运行此测试时,会得到以下结果:
v0.8.28     ->  2716 ms
v0.10.40    -> 73570 ms
v0.12.7     -> 92427 ms
iojs v2.4.0 ->   510 ms
chrome      ->  1473 ms

我还尝试了在异步循环中运行此测试(每个循环的步入不同的滴答声),但结果与上面显示的结果相似。

我不明白为什么此测试在较新的节点版本中如此昂贵。
为什么这么慢?
是否有任何特殊的v8标志可以改善此测试?

最佳答案

为了处理大型和稀疏阵列,内部有两种类型的阵列存储:

  • 快速元素:紧凑型键集的线性存储
  • 字典元素:哈希表存储,否则为

  • 最好不要使阵列存储从一种类型翻转到另一种类型。

    所以:
  • 对数组使用连续的键(从0开始)
  • 不要将大型数组(例如> 64K元素)预分配为最大大小,而是随着
  • 的增长而增长
  • 不要删除数组中的元素,尤其是数字数组
  • 不加载未初始化或删除的元素

  • 来源和更多信息:http://www.html5rocks.com/en/tutorials/speed/v8/

    PS:在即将发布的node.js + io.js版本中,这应该会大大改善。

    09-19 10:43