【问题标题】:Is it worth it to convert array into set to search in NodeJS将数组转换为集合以在 NodeJS 中搜索是否值得
【发布时间】:2019-12-31 12:15:10
【问题描述】:

我想知道是否值得将数组转换为集合以便使用 NodeJS 进行搜索。

我的用例是多次进行此搜索,但在大数据集上不是必需的(有时可以在数组中增加约 2000 个项目)。

在列表中查找特定 id。

哪种方法更好:

const isPresent = (myArray, id) => {
   return Boolean(myArray.some((arrayElement) => arrayElement.id === id);
}

const mySet = new Set(myArray)
const isPresent = (mySet, id) => {
   return mySet.has(id);
}

我知道理论上第二种方法更好,因为第一种方法是 O(1) 和 O(n)。但是集合的实例化可以抵消小数组的增益吗?

【问题讨论】:

  • 如果搜索过于频繁,IMO 设置肯定会比一些更好,你也不需要明确地将 some 的输出更改为布尔值,它始终是 boolean 值,只有默认
  • 你也可以查看 hashMap。搜索数组需要循环,而搜索 SetHashMap 需要查找。对于n 项的数组,更糟糕的情况是n 迭代,但对于Set/HashMap,它的1。您可以参考:stackoverflow.com/questions/17295056/…
  • @CodeManiac 谢谢你的回答!为了清楚起见,这里做了很多搜索,但每次都在不同的数组上。对于每次搜索,都会导致新集合/哈希图的实例化。我可能会尝试发布此差异并告诉我是否看到性能有任何改进。
  • 如果你每次都构建一个新的Set,那肯定不是更好。 Set 构造遍历整个数组,然后执行更多操作,但数组搜索遍历数组的一小部分。
  • @Pierre-LouisLacorte 如果您每次搜索时都有新数组,那么创建Set 使用binary search or any other suitable algo 没有任何意义,但是如果数组发生变化,可以通过添加或删除一个来表示或前一个数组中的更多 id,而不是您可以在初始数组上使用 Set 并且要添加删除 id,您可以使用 Set 本身并在需要时搜索值

标签: javascript arrays node.js optimization set


【解决方案1】:

@jonrsharpe - 特别是对于您的情况,我发现将 2k 数组转换为 Set 本身需要 ~1.15ms。毫无疑问,搜索 Set 比 Array 更快,但在您的情况下,这种额外的转换成本可能很小。

您可以在浏览器控制台中运行以下代码进行检查。 new Set(arr) 花费了大约 1.2 毫秒

var  arr = [], set = new Set(), n = 2000;
for (let i = 0; i < n; i++) {
  arr.push(i);
};

console.time('Set'); 
set = new Set(arr);
console.timeEnd('Set');

在 Set 中添加元素总是很昂贵的。 下面的代码显示了在数组/集合中插入项目所需的时间。这表明 Array 插入比 Set 快。

var  arr = [], set = new Set(), n = 2000;
console.time('Array'); 
for (let i = 0; i < n; i++) {
  arr.push(i);  
};
console.timeEnd('Array');

console.time('Set'); 
for (let i = 0; i < n; i++) {
  set.add(i);  
};
console.timeEnd('Set');

我运行下面的代码来分析在数组和集合中定位元素的速度。发现 set 比数组快 8-10 倍。

您可以将此代码复制粘贴到浏览器中以进一步分析

var arr = [], set = new Set(), n = 100000;
for (let i = 0; i < n; i++) {
  arr.push(i);
  set.add(i);
}

var result;
console.time('Array'); 
result = arr.indexOf(12313) !== -1; 
console.timeEnd('Array');
console.time('Set'); 
result = set.has(12313); 
console.timeEnd('Set');

所以对于你的情况 array.some 更好!

【讨论】:

    【解决方案2】:

    我将为使用 Set 提供不同的好处:您的代码现在更加语义,更容易了解它的作用。

    除此之外,这篇文章有一个很好的比较 - Javascript Set vs. Array performance 但如果您真的觉得这是您的瓶颈,请自行测量。不要优化 not your bottleneck 的东西!

    我自己的启发式方法是类似isPresent 的实用程序,用于更好的代码,但如果检查是在循环中完成的,我总是在之前构造一个Set

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多