【问题标题】:JavaScript Performance: Loop and indexOf with large ArraysJavaScript 性能:大数组的循环和 indexOf
【发布时间】:2019-07-30 12:05:13
【问题描述】:

我目前遇到了 JavaScript 操作的性能问题。

我想为那些 ID 已经在数组 aInvited 中或不在 aInvitationAllowed 数组中的对象清理一个对象数组 (aEmployees):

var iLength = aEmployees.length - 1;
for (var i = iLength; i >= 0; --i) {
   if (aInvited.indexOf(aEmployees[i].id) !== -1 || aInvitationAllowed.indexOf(aEmployees[i].id) === -1) {
      aEmployees.splice(i, 1);
   }
}

您可以想象我有 Employee 对象 (aEmployees)。我还有一个已被邀请参加活动的员工 ID 列表 (aInvited) 和一个允许被邀请参加活动的员工 ID 列表 (aInvitationAllowed)。我希望所有员工因此我仍然可以邀请参加活动。

问题在于indexOf 查询的行。我必须假设数组有很多条目(~ 100,000 个条目)。那么可能是循环需要一段时间。

所以我的问题是:我怎样才能使循环更快? indexOf 有更快的替代方案吗?

感谢您的提示!

【问题讨论】:

  • 不确定是否有帮助,但请看这里developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 理想情况下,您不要让数组接近那么大!
  • 循环一次邀请数组并使用invited[employee.id] = true 创建一个数组。然后你可以检查if (invited[id]===true) {}
  • @AustinTFrench 当然......但是,在这种情况下,我目前没有其他选择。

标签: javascript arrays performance loops indexof


【解决方案1】:

考虑改用Set 进行比较。 Set.hasO(1) 操作,而 indexOfO(n) 操作,将整体计算复杂度降低到 O(n) 而不是 O(n^2)

const aInvitedSet = new Set(aInvited);
const aAllowedSet = new Set(aAllowed);

const iLength = aEmployees.length - 1;
for (let i = iLength; i >= 0; --i) {
  const { id } = aEmployees[i];
  if (aInvitedSet.has(id) || !aAllowedSet.has(id)) {
    aEmployees.splice(i, 1);
  }
}

另外,splice 很慢。除非您必须改变现有数组,否则您可能会考虑将 .push 改为一个新数组(看起来是 faster 而不是 Array.prototype.filter):

const aInvitedSet = new Set(aInvited);
const aAllowedSet = new Set(aAllowed);
const newArr = [];

const iLength = aEmployees.length;
for (let i = 0; i < iLength; i++) {
  const employee = aEmployees[i];
  const { id } = employee;
  if (!aInvitedSet.has(id) && aAllowedSet.has(id)) {
    newArr.push(employee);
  }
}

【讨论】:

  • @CertainPerformance 欣赏!我会试一试。
  • 这个答案对我来说很完美!我的 JS 代码的执行时间有了很大的改进。
  • 我发现IE11不支持Set。你知道这种情况的替代方案吗?
  • 假设ids都是一种类型,字符串或数字,您可以使用对象属性查找代替,例如if (id in aInvitedObj &amp;&amp; !(id in aAllowedObj))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-12
  • 1970-01-01
  • 2016-02-08
  • 2012-07-09
  • 2018-04-21
  • 1970-01-01
  • 2015-03-21
相关资源
最近更新 更多