みかづきブログ・カスタム

基本的にはちょちょいのほいです。

要素の多いがユニークな配列に特定の要素が含まれているか調べるときにSet.prototype.hasを検討する 🔍


const target = 'user-8823';
const hasTarget = users.includes(target);

みたいなコードで、要素の多いユニークな配列から、特定の要素が含まれているかを確認するコードを高速で動かそうと思った時に、

const target = 'user-8823';
const set = newSet(users);
const hasTarget = set.has(target);

みたいにSet.prototype.hasを使うことを検討したのですが、

意外と、

const target = 'user-8823';
const str = users.join(',');
const regExp = new RegExp(`\\b${ target }\\b`);
const hasTarget = regExp.test(target);

と正規表現で探すのが早かったりしないかな。と考えて、3つのコードを計測してみました。

ソースコード

const exponent = 6;
const length = Math.pow(10, exponent);
const array = Array.from({ length }, (_, i) => `user-${String(i).padStart(exponent, '0')}`);

const set = new Set(array);

console.time('Set.prototype.has');
console.log(set.has(`user-${ String(length -1).padStart(exponent, '0') }`));
console.timeEnd('Set.prototype.has');

const str = array.join(',');
const regExp = new RegExp(`\\buser-${ String(length -1).padStart(exponent, '0') }\\b`);

console.time('RegExp.prototype.test');
console.log(regExp.test(str));
console.timeEnd('RegExp.prototype.test');

console.time('Array.prototype.includes');
console.log(array.includes(`user-${ String(length -1).padStart(exponent, '0') }`));
console.timeEnd('Array.prototype.includes');

こんな感じのコードで計測します。

結果

100件の配列

  • Set.prototype.has: 0.076171875 ms
  • RegExp.prototype.test: 0.056884765625 ms
  • Array.prototype.includes: 0.02197265625 ms

1,000件の配列

  • Set.prototype.has: 0.06982421875 ms
  • RegExp.prototype.test: 0.06201171875 ms
  • Array.prototype.includes: 0.02587890625 ms

10,000件の配列

  • Set.prototype.has: 0.10693359375 ms
  • RegExp.prototype.test: 0.126953125 ms
  • Array.prototype.includes: 0.052978515625 ms

100,000件の配列

  • Set.prototype.has: 0.114013671875 ms
  • RegExp.prototype.test: 0.72607421875 ms
  • Array.prototype.includes: 0.305908203125 ms

1,000,000件の配列

  • Set.prototype.has: 0.114990234375 ms
  • RegExp.prototype.test: 6.451171875 ms
  • Array.prototype.includes: 2.7548828125 ms

結論

(配列の要素にもよるだろうが)10,000件程度であれば、Array.prototype.includesが早い。
10,000〜100,000件を超えるのであればSet.prototype.hasを検討しても良いかもしれない。
正規表現は思ったよりも早くなかった。

DEMO

https://jsfiddle.net/kimizuka/8wetug29/15/

ログに計測結果が出力されます。