今回やること
この記事では、全角・半角判定を題材に、正規表現版、数値比較版、ビット演算版を簡単にベンチマークします。
ベンチマークは「どちらが常に速いか」を決めるものではなく、自分の条件で差が出るかを確認するためのものです。
前提条件
- Node.jsを実行できる
- ターミナルを使える
- 計測結果は環境によって変わると理解している
Step 1: ファイルを作る
width-benchmark.mjs を作ります。
import { performance } from "node:perf_hooks";
const samples = ["A", "1", "!", "ア", "ン", "あ", "ア", "漢"];
const loop = 5_000_000;
Step 2: 正規表現版を書く
const halfwidthRegex = /^[\x20-\x7E\uFF61-\uFF9F]$/;
function isHalfwidthRegex(char) {
return halfwidthRegex.test(char);
}
1文字だけを判定するため、^ と $ を付けています。
Step 3: 数値比較版を書く
function isHalfwidthNumeric(char) {
const code = char.charCodeAt(0);
return (code >= 0x20 && code <= 0x7e) || (code >= 0xff61 && code <= 0xff9f);
}
ASCII印字可能文字と半角カタカナだけを半角扱いにします。
Step 4: ビット演算版を書く
function isHalfwidthBitwise(char) {
const code = char.charCodeAt(0);
if ((code & 0xff80) === 0 && code >= 0x20 && code <= 0x7e) {
return true;
}
if ((code & 0xff00) === 0xff00) {
const lower = code & 0x00ff;
return lower >= 0x61 && lower <= 0x9f;
}
return false;
}
学習用の例として書いています。実務では、まず数値比較版のような読みやすい形を検討します。
Step 5: 計測関数を書く
function bench(label, fn) {
let count = 0;
const start = performance.now();
for (let i = 0; i < loop; i++) {
const char = samples[i % samples.length];
if (fn(char)) count++;
}
const end = performance.now();
console.log(`${label}: ${(end - start).toFixed(2)}ms count=${count}`);
}
結果が使われない処理は最適化で消える可能性があるため、count を出力しています。
Step 6: 実行する
bench("regex", isHalfwidthRegex);
bench("numeric", isHalfwidthNumeric);
bench("bitwise", isHalfwidthBitwise);
実行します。
node width-benchmark.mjs
結果の読み方
| 見るもの | 注意 |
|---|---|
| 実行時間 | PC、Node.js、入力データで変わる |
| 倍率 | 小さい差なら誤差かもしれない |
| 入力データ | ASCII中心か、日本語中心かで変わる |
| 可読性 | 速くても読みにくいと保守コストが上がる |
よくあるエラー
| エラー | よくある原因 | 確認すること |
|---|---|---|
import が使えない | .js で実行している | .mjs にするか設定を変える |
| 結果が毎回違う | JITや負荷の影響 | 複数回実行する |
| 速い方が逆転する | 入力データが違う | データセットを分ける |
| 正規表現が遅すぎる | 毎回生成している | ループ外で作る |
学習用と本番用の違い
学習では小さなベンチマークで違いを見るだけで十分です。本番では、実データ、実行環境、I/O、メモリ、ログ出力、全体処理時間を含めて測ります。
マイクロベンチマークで速くても、アプリ全体の体感速度が改善するとは限りません。
まとめ
正規表現、数値比較、ビット演算は、それぞれ速度と読みやすさが違います。全角・半角判定のような小さな処理では差が出ることもありますが、実務では実データで測り、可読性と保守性も含めて判断します。