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を検討しても良いかもしれない。
正規表現は思ったよりも早くなかった。