フロントエンド開発Blog

オレには鈍器がある

JavaScript , 検索

JavaScriptを書いてて「文字列の中に特定の文字が含まれるか否か」を判定したいとき、皆さんだったらどうやって書きますか?私は長いこと「ただの文字列ならindexOf」「正規表現なら.test」を使ってました。

これは5年位前に計測したときにindexOfが早かったのを覚えていてそのときの経験則からそうしていただけに過ぎません。

ここらでもう一回計測してみようと思い立って試験的にコードを書いてみました。

performance.nowを使って計測しています。なお、計測結果はconsoleに出力されます。

コードを見ていただくと分かるかと思いますが、いろんなパターンで計測してます。

- 検索元のとなる本文の大小2パターン
- 検索対象となる文字列の大小2パターン
- 一致する場所が前方か後方か2パターン

上記の組み合わせ全8パターンあります。それらに対してindexOf、match(文字列)、match(正規表現)、.testの4種の方法で判定処理を書き、計測します。なお、ループでそれぞれ5000回判定するようにしました。

※計測はchrome最新版で実施しました。別のブラウザ、別の文字列だと今回のテスト結果と異なることも十分にありますので鵜呑みしないようお願いします。以下計測結果です。

# str.indexOf(char) str.match(char) str.match(regexp) regexp.test(str)
パターン1:
検索元:大
検索対象:大
一致する場所:前方
1.0299999999999976 12.100000000000005 3.8999999999999986 1.9600000000000009
パターン2:
検索元:大
検索対象:大
一致する場所:後方
9.005000000000003 15.415000000000006 8.595000000000013 6.140000000000015
パターン3:
検索元:大
検索対象:小
一致する場所:前方
0.8199999999999932 4.999999999999986 1.5300000000000011 0.8999999999999915
パターン4:
検索元:大
検索対象:小
一致する場所:後方
3.1500000000000057 7.319999999999993 3.7749999999999915 3.2700000000000102
パターン5:
検索元:小
検索対象:大
一致する場所:前方
0.7650000000000006 6.5249999999999915 1.5 0.8999999999999915
パターン6:
検索元:小
検索対象:大
一致する場所:後方
0.8750000000000142 6.929999999999993 1.7300000000000182 1.0299999999999727
パターン7:
検索元:小
検索対象:小
一致する場所:前方
0.44999999999998863 4.669999999999959 0.9849999999999852 0.6050000000000182
パターン8:
検索元:小
検索対象:小
一致する場所:後方
0.7199999999999989 5.2450000000000045 1.4150000000000205 0.9049999999999727

8パターンのうち7パターンがindexOfでした。しかし詳しく見ていくとパターン1以外は.testとそこまで大きな差は無いように見えます。

.testは「大量のテキストかつ一致する場所が後方」というシチュエーションに強いようです。逆に言うとindexOfはその条件下での判定に弱いのかもしれませんね。

大抵のケースではindexOfで事足りるようですが、「大量のテキストの中から特定の文字を検索する」ケースでは.testも選択肢に入れたほうが良さそうです。一致場所が前方か後方かなんてまぁ分からないことのほうが多いですからね。

上記のブログを参考にするなら複数条件の場合は.testのほうが分かりやすくてパフォーマンスも高そうです。ざっとコード書いて計測してみたところ

- indexOfで最初の条件にマッチする場合 2.1700000000000017
- indexOfで最初の条件にはマッチせず次の条件にマッチする場合 6.169999999999995
- testで複数条件を指定した場合 2.780000000000001

のような結果が。testでの判定が安定していそうですね。今日のところはここらへんで。。

ページトップへ

関連ページ

ページトップへ