各种浏览器中对象属性访问的JavaScript性能

时间:2014-01-28 09:40:01

标签: javascript performance

我想详细说明this question。问题是,如果对象的访问时间是恒定的,即独立于属性的数量。 answer是,它确实是不变的。

我在quick testjsFiddle但是(至少对于Chrome)显示,对象的访问时间与10个属性之间存在非常显着的差异(~3倍)具有100k属性的对象。

所以第一个问题是。访问时间是否真的不变,差异是由于内存管理导致的测量不精确或与初始化有关而不是访问?

然后thg435创建了benchmark,在其中很容易看到各种浏览器中大小对象的访问时间之间的差异,例如IE和Safari显示大型和小型对象之间没有区别(两者都基本上非常慢),而Firefox甚至更多Opera和Chrome在访问时间方面表现出巨大差异。但它也显示了浏览器速度之间令人难以置信的差异(例如IE比Firefox或Chrome慢50-100倍)。

我的第二个问题就是 - 这些结果可以信任吗?或者也许一些优化(在真正的JS代码中不会产生这么大的差异)会严重降低结果?如何制定访问变量的基准,这是公平的吗?我已经制作second benchmark以避免优化,不仅可以访问变量,还可以使用其值(以测量数字运算为代价),这会降低Chrome和Opera的疯狂速度,但仍然IE的速度比100倍慢。我知道,IE很慢。但是这么快就听起来很可疑。

已更新:我添加了third benchmark,旨在更好地解决复杂问题。

脚注:它不允许我在没有代码的情况下发布带有jsfiddle链接的问题,所以这里是测试代码。

function go(amount) {
  var object1 = {};
  for (var i = 0; i < amount; i++) {
    object1['id' + i] = i;
  }

  var start = new Date().getTime();
  var j = 0;
  for (var i = 0; i < 100000000; i++) {
    j += object1['id3'];
  }
  var end = new Date().getTime();
  console.log(j);
  document.getElementById('result').innerHTML = end - start;
}

1 个答案:

答案 0 :(得分:2)

基本上,JavaScript中的对象可以被认为是哈希映射(与值配对的列表/键数组)。

存在几种不同的实现方式,并且底层实现应该如何工作的标准没有限制。您可以创建一个简单的数组来搜索每个索引中的键。

想象一下有人实际上使用了数组来实现上面描绘的地图,插入可以很快完成 - 只需将数组推到数组的末尾即可。删除也会相当快(假设您手头有对的索引)。但是找到正确的索引很可能与数组中的项目(对)数量呈线性关系。查找索引是此模型中对象值查找的必要条件。

JS引擎可能会使用某种搜索树结构来优化查找时间 - 但价格是插入或删除会受到影响 - 或两者兼而有之。

一个明智的假设是查找比插入更频繁地执行。因此,实现了一个好的搜索树(最有可能基于AVL - http://en.wikipedia.org/wiki/AVL_tree)。

不同的搜索树在插入,删除和查找的速度方面具有不同的属性。另一个属性是保留插入顺序。在上面概述的“傻瓜阵列实现”中,插入顺序被保留,而在许多搜索树中,情况并非如此。 ECMA标准中没有说明您不能依赖键的顺序(某些树实现甚至可能在插入,删除甚至查找键时重新排序!)。但是,某些浏览器表明保留了插入顺序。只是,不要相信未来或其他浏览器平台的情况。

换句话说:您不能假定任何O(1)运行时间用于查找,插入或删除。很可能你会看到符合O(log N)的东西,但它可能在JS引擎之间有所不同。