为什么在新节点版本中使用字母数字键创build对象的速度太慢?

我在不同的节点版本中运行这个testing:

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(); 

正如你所看到的,它只是创build一个有100000个字段的对象,其中每个字段只是一个只有一个字段的对象。 这个内部对象的关键是强制字母数字(如果该键是数字,它执行正常)。

当我在不同的JavaScript实现/版本中运行这个testing时,我得到了这样的结果:

 v0.8.28 -> 2716 ms v0.10.40 -> 73570 ms v0.12.7 -> 92427 ms iojs v2.4.0 -> 510 ms chrome -> 1473 ms 

我也尝试在一个asynchronous循环中运行这个testing(每个循环步骤都用不同的勾号),但是结果与上面显示的类似。

我不明白为什么这个testing在更新的节点版本中如此昂贵。 为什么这么慢? 有什么特殊的v8标志可以改进这个testing吗?

为了处理大型和稀疏的数组,内部有两种types的数组存储:

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

最好不要导致arrays存储从一种types翻转到另一种types。

因此:

  • 数组从0开始使用连续的键
  • 不要预先分配大的数组(例如大于64K的元素)到它们的最大尺寸,而是随着你的增长而增长
  • 不要删除数组中的元素,特别是数值数组
  • 不要加载未初始化或已删除的元素

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

PS:在即将到来的node.js + io.js版本中,这应该会有相当大的改进。