JavaScript对象与数组查找性能对比

21
JavaScript对象中通过键检索值与迭代单个JavaScript对象数组之间的性能差异是什么?
在我的情况下,我有一个JavaScript对象,包含用户信息,其中键是用户的ID,值是每个用户的信息。
我之所以问这个问题,是因为我想使用angular-ui-select模块选择用户,但我不能使用JavaScript对象-它需要一个数组。
通过切换从按键查找到按迭代查找,我会失去多少东西(如果有的话)?
按键:
var user = users[id];

通过迭代

var user;

for (var i = 0; i < users.length; i ++) {
  if (users[i].id == id) { 
    user = users[i]; break;
  }
}

3
不要混淆 JavaScript 对象和 JSON! - Felix Kling
这很不公平:线性搜索(数组循环)与几乎随机访问(哈希表实现)。 - wnrph
这里有一个快速的基准测试,可能会对您有所帮助:http://jsben.ch/#/Y9jDP - EscapeNetscape
这种做法已经过时,现在你需要使用以下方式: users.find(user => user.id === id)这是修复后的基准测试:http://jsben.ch/#/UM0ju - Hatch
@Hatch 或许可以,但是如果你需要支持旧版浏览器的话就不行了。你需要一个 polyfill 来支持该方法以及一个转译器来处理 => 箭头函数。 - Phil Cooper
3个回答

21

这个问题的答案取决于不同的浏览器,jsperf.com 上有一些关于这个问题的性能测试。同时这也与你的数据大小有关。通常当你有大量的数据时,使用对象键值对比数组更快。对于小型数据集,数组可以更快。

数组搜索在目标项在数组中的位置不同的情况下具有不同的性能。对象搜索将具有更一致的搜索性能,因为键没有特定的顺序。

另外,循环遍历数组比循环遍历键更快,所以如果您计划对所有项目进行操作,将它们放在数组中可能是明智之举。在我的某些项目中,我两者都做,因为我需要进行批量操作并快速查找标识符。

一个测试:

http://jsben.ch/#/Y9jDP


从第二个链接来看,for循环比其他任何方法都要快得多。我本以为直接在对象中查找(知道键)会更快。 - user3594595
2
好的,红色测试结果(最快的那个)是一个最佳情况下的数组搜索。被搜索的项是第一个,自然会很快。如果你看最坏的情况,即该项在数组中最后出现,那么速度就会慢得多。对象搜索具有相当一致的查找性能,与位置无关。 - Ole Borgersen
2
使用适当的高效解决方案修复了您的测试:http://jsben.ch/#/UM0ju - Hatch
正如Ole提到的那样,对于大量项目,对象查找的性能比循环遍历数组要高得多,即使使用最高效的数组函数也是如此。这里有一个测试,其中包含10,000个项在一个数组中,每个项中有10个键/值对,显示对象与数组相比的> 1000倍改进:https://jsperf.com/object-key-vs-array-find。我的测试代码不是最好看的; 如果我漏掉了什么,请告诉我。 - Ari

4

这个问题涉及到所有编程语言。它取决于许多因素:

  • 集合的大小——当你查找最后一个关键字并且数组很长时,数组会变慢。
  • 元素是否可以重复——如果是,那么你需要一个数组。如果不是,你需要一个字典(map),或者你需要编写一个添加方法,对于每个添加将迭代你的数组并查找可能的重复项,这可能会在处理大型列表时带来麻烦。
  • 平均关键字使用率——如果最常请求的用户ID位于列表末尾,性能会降低。

在你的例子中,使用map会是更好的解决方案。其次,你需要在你的代码中添加一个break :)

var user;

for (var i = 0; i < users.length; i ++) {
  if (users[i].id == id) {
     user = users[i]; break;
  }
}

否则,您的性能将会下降:)

-6

关联数组比带编号索引的数组慢得多,因为关联数组通过进行字符串比较来工作,而字符串比较比数字比较要慢得多!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接