3GBで負けたと思っていたら、勝っていた(ただし冷えていれば) — 単発 grep は譲って、調査の残り全部で勝つ

技術解説

3GB の grep は、ファイルがキャッシュに載っていれば ripgrep の勝ちです。載っていなければ、uvp の勝ちです。

前の記事で「3GB は ripgrep の土俵、そこは譲る」と書きました。ファイルがメモリに載るサイズでは、索引を持つ意味が薄い——そう思って、ずっと温まった状態でばかり測っていました。キャッシュを捨てて測り直したら、逆でした。そこも含めて、3GB で勝てる場面を並べ直します。

先に結論

3GB のファイル(OpenStreetMap 日本 XML から切り出した 3,032,812,644 byte)で、ripgrep / sed / gzip と uvp を同じ作法で比べました(Apple M4 / メモリ32GB / 外付け USB SSD、/usr/bin/time -p の real。検索はコールド=sudo purge 直後ウォーム=その直後の2回目の両方を測り、.uwvz は作成済み)。

  • 純粋な検索は、キャッシュの状態で入れ替わります。温まっていれば ripgrep(0.33秒 対 1.01秒)、冷えていれば uvp(3.26秒 対 1.25秒=2.6倍)。uvp の起動+索引ロードの固定費 1秒弱が、rg の全走査より大きいか小さいかの勝負で、絶対差はどちらに転んでも 0.7秒以内です
  • それでも 3GB で勝てる場面が4つあります。① 直して保存する(置換は sed の3.5倍・抽出は12.6倍)、② rg に無い操作を使う(順序検出・±N文脈の絞り込み・クリック降下)、③ gz/zip で保管している(解凍+rg 6.47秒 対 .uwvz 直接 0.68秒=9.5倍)、④ 何を調べるか決まっていない(CLI で絞って GUI で見て、また絞る。0.24秒/段)
  • まとめると、grep で終わる日は rg でいい。調査=読む・絞る・数える・直す・保存する、のどれか1つが入った瞬間、3GB でも uvp の土俵になる

まず、冷やして測り直す

まず、純粋な検索を2つの状態で測り直しました。コールドsudo purge の直後(ファイルがページキャッシュに無い)、ウォームはその直後にもう一度(メモリに載っている)。uvp 1.6.3、ripgrep 15.2.0、いずれも .uwvz は作成済みです。

コールド(しばらくぶりに開くとき)

検索 rg uvp rg ÷ uvp 件数
固定文字列 3.26秒 1.25秒 2.6倍 11,274
大小無視 -i 3.30秒 1.58秒 2.1倍 940,482
正規表現 -E 3.32秒 1.70秒 2.0倍 928,301
正規表現(行頭つき) 3.24秒 1.47秒 2.2倍 222,072
正規表現+大小無視 3.29秒 1.69秒 1.9倍 491,643
除外 -E -v 3.57秒 1.85秒 1.9倍 1
除外 -v(素の語) 3.51秒 3.96秒 1/1.1 7,698,790

7つのうち6つで uvp が速く、だいたい2倍。理由は 10GB・50GB とまったく同じで、読むバイト数が 1/12 で済むからです(3,032,812,644 byte 対 251,829,224 byte)。

ウォーム(直前に読んだファイルに、続けて聞くとき)

検索 rg uvp rg ÷ uvp
固定文字列 0.33秒 1.01秒 1/3.1
大小無視 -i 0.65秒 1.22秒 1/1.9
正規表現 -E 0.52秒 1.28秒 1/2.5
正規表現(行頭つき) 0.48秒 1.16秒 1/2.4
正規表現+大小無視 0.61秒 1.40秒 1/2.3
除外 -v(素の語) 2.10秒 3.74秒 1/1.8
除外 -E -v 3.13秒 1.74秒 1.8倍

温まると、6つで rg が勝ちます。3GB は 32GB のメモリに収まるので、一度読めば全体がキャッシュに載り、その上を素直に走る rg が 0.33秒。uvp は本体を起動してから索引を読む固定費が先に立ちます。ここは譲ります。差は 0.7秒なので、譲っても実務では何も起きません。

例外が1つ。-E -v(除外)だけはウォームでも uvp が速い(1.74秒 対 3.13秒)。除外は全行を相手にする操作なので、rg 側にキャッシュの利が効きにくく、読むバイト数の差がそのまま出ます。

10GB では、そもそもウォームが存在しない

10GB コールド ウォーム
rg(固定文字列) 10.96秒 10.89秒
uvp.uwvz 1.16GB) 2.37秒 1.55秒

2回目も同じ 10.96秒です。32GB のメモリにファイルが収まらないので、何度読んでもディスクから読み直すことになる。「3GB なら rg」が成り立つのは、ファイルがメモリに載って、かつ直前に誰かが読んでいるときだけ、ということになります。再起動直後・数日ぶりに開くログ・USB HDD・ネットワークドライブでは、3GB でも読むバイト数の差がそのまま出ます。

問題は、調査が「grep 1回」で終わることがほとんど無い、という点です。

① 直して保存する日 — 出力を書く仕事は、読む量がそのまま効く

検索は「読んで数える」仕事ですが、抽出と置換は「読んで書き出す」仕事です。ここで様子が変わります。

確認 CLI uvp 倍率
ヒット行の抽出(sed -n '/語/p' 9.96秒 0.79秒 12.6倍
全置換(sed 's/A/B/g' 15.04秒 4.28秒 3.5倍
同(rg --passthru -r 4.28秒 1.7倍

sed は1行ずつ処理するので、3GB でも 10〜15秒かかります。uvp は 0.25GB の索引から必要な行だけ取り出して書くので、3GB でも勝ちます。置換の出力は sed および rg --passthru -r と、試した全組み合わせでバイト単位まで一致しています。

「調査して、直して、保存する」という1日の流れで足し合わせると、こうなります。

開く → 調査2回 → 置換して保存(3GB) 合計
rg + sed 17.7秒
uvp(索引作成を含む) 7.6秒2.3倍

uvp の 7.6秒には、1回目の索引作成 1.2秒が入っています。それでも勝ちます。置換 1回が sed の 15秒を uvp の 4.3秒にするからで、その差 10秒の前では索引の 1.2秒は誤差です。

② rg に無い操作を使う日

比較表に「参考」としてしか載せられなかった項目があります。rg 側に相当するコマンドが無いからです。

操作 uvp(3GB) rg でやるなら
順序検出 -seq login,timeout,restart(この順に現れる流れだけ) 0.99秒 awk で状態機械を書く
±N 行の中に2語目 -C 3 <語2>(近傍共起) 1.23秒 rg -C 3 \| rg では文脈行が混ざり、意味が変わる
集計の値をクリックしてその値で次の段へ GUI で即時 rg -o \| sort \| uniq -c を見て、もう一度 rg
ヒット行から原本の行番号つきで本文へジャンプ GUI で即時 rg -n の行番号を控えて sed -n 'Np'

「速い・遅い」の前に、比較そのものが成立しない項目です。「ログイン失敗の3行後にタイムアウトがある流れだけ」「この値の周辺5行に別の語があるものだけ」——調査でこのどれか1つでも使うなら、3GB かどうかは関係なくなります。

③ gz / zip で保管している日 — 探すたびに戻さない

ログは普通、gzip で固めて置いてあります。探すときは戻してから rg——zgrep を使っても、解凍そのものは省けません。

同じ 3GB を gzip -6zip -6.uwvz で固めて、戻して探す時間と直接探す時間を並べました。

3GB 固めるのにかかる時間 大きさ 探す(解凍+rg/直接)
gzip -6 16.8秒 0.30GB(1/10.1) 6.47秒(解凍 3.49+rg 2.98)
zip -6 19.4秒 0.30GB(1/10.1) 8.71秒(解凍 8.08+rg 0.63)
.uwvz 1.2秒 0.25GB(1/12.0) 0.68秒(直接検索)

大きさは gzip と同じで、作るのは14倍速く、探すのは 9.5倍速い。理由は、gzip は探すたびに全部戻すのに対し、.uwvz は索引を持っているので戻さずに探せるからです。2問目・3問目も 0.68秒のまま。gzip は戻したファイルを残しておけば2問目から rg の 0.33秒ですが、それでは圧縮した意味がありません。

そして .uwvz-extract で元のファイルにバイト一致で戻せます(無料)。保管形式を gz から .uwvz に変えるだけで、3GB でも毎回の解凍が消えます。50GB なら gzip 2分に対して 7秒、17倍です。

④ 何を調べるか決まっていない日 — ここが本題

負けの表で、3GB の「東京」は 11,274件ヒットしています。rg の 0.33秒には、この 11,274行を人が読む時間が入っていません。

調査には2種類あります。「この文字列があるか」を確かめる調査と、何を探せばいいかまだ分かっていない調査です。後者は、11,274件を眺めて、気になる行の前後を見て、別の語で絞って、数えて、また戻る——試行錯誤そのものです。ターミナルでやるなら、そのたびにコマンドを組み直して 0.33秒——ではなく、組み直す時間と、流れていく出力を目で追う時間を払います。

uvp の末尾に -open を付けると、CLI の結果がそのまま GUI に渡ります。

uvp japan-dv-ai.uwvz '東京' -uniq 'k="([^"]+)"' -sort count -head 20 -open

ターミナルで uvp の検索と集計を実行し、末尾に -open を付けたところ。CLI 側の結果が出たあと GUI が起動する

  • CLI が検索と集計を済ませ、結果を一時ファイルで GUI に渡す(GUI は検索し直しません。v1.6.2)
  • GUI は同じ .uwvz を読むので、開き直しに 3GB を読まない(2回目以降のオープンは 47.73GB のファイルで 0.02〜0.07秒。3GB ならそれ以下)
  • 一覧の行をクリックすると本文の該当位置へ。±N 行の文脈。集計の値をクリックすると、その値で次の段へ
  • 別の語で絞り直す——0.24秒/段(50GB での実測。3GB ならそれ以下)
  • 見当がついたら、またコマンドに戻って一括で処理する。GUI と CLI は同じ .uwvz を使うので、行き来に待ち時間が無い

GUI 側で CLI の結果を受け取った状態。結果一覧・集計ランキング・本文が並び、ここから別の語で再検索できる

つまり比べるべきは「grep 1回の 0.33秒 対 1.01秒」ではなく、「答えに着くまでの総時間と操作数」です。rg だけで進めると、絞り直すたびにコマンドを組み直し、出力を読み、また組み直す。GUI だけで進めると、開くのが遅い。索引を挟んで CLI と GUI が同じものを使えば、コマンドで大きく絞って、画面で細かく見て、もう一度コマンドに戻る、が待ち時間なしでつながります。

CLI と GUI は同じ関数を呼んでいるので(絞り込み・集計・順序)、CLI で出た件数と GUI で出た件数は必ず一致します。ここは 81項目+gz/zip 12項目+258GB 全項目を rg / sed とバイト単位で突き合わせて確認済みで、製品側の誤りは 0 件でした。

まとめ — 3GB で勝つ4つの場面

場面 3GB での実測
grep で終わる日 温まっていれば rg の勝ち(0.33秒 対 1.01秒)。冷えていれば uvp の勝ち(3.26秒 対 1.25秒=2.6倍)。除外 -E -v だけは温まっていても uvp(1.74秒 対 3.13秒)
① 直して保存する日 置換 sed 比 3.5倍・抽出 12.6倍。「開く→調査2回→置換して保存」で 2.3倍
② rg に無い操作を使う日 順序検出・近傍共起・クリック降下・行番号ジャンプ。比較が成立しない
③ gz/zip で保管している日 解凍+rg 6.47秒 対 直接 0.68秒9.5倍)。作るのも gzip の 1/14 の時間
④ 何を調べるか決まっていない日 CLI で絞って GUI で見て、また絞る。0.24秒/段。比べる単位が「grep 1回」から「答えに着くまで」に変わる

「温まった 3GB の単発 grep」は rg の土俵で、そこは譲ってよい。冷えていれば 3GB でも uvp が2倍速く、調査=読む・絞る・数える・直す・保存する、のどれか1つでも入った瞬間に uvp の土俵になります。そして 10GB を超えれば、純検索でも 5〜10倍で勝ちます。

使っている道具

uvpUwView Pro v1.6.3 に付属します(Windows・macOS・Linux、1ライセンスで全OS。買い切り/月額。14日間の無料試用あり——試用中も uvp と編集機能が使えます)。置換(-replace)は Edit Upgrade の機能です。.uwvz からの復元(-extract)は無料です。無料版 UwViewuvf は検索と -open のみで、索引を持ちません(v1.6.3 で1回読みに作り直し、3GB コールドで 3.32秒=rg とほぼ同じになりました)。

数値はすべて当方環境での自社実測で、独立ベンチマークではありません。ripgrep は多数ファイルの横断検索では最速の部類で、この記事はそこを争っていません。設定の問題があればご指摘ください。確認のうえ訂正します。

測定条件

  • Apple M4 / メモリ32GB / macOS 26.3.1 / 外付けSSD
  • ripgrep 15.2.0 / BSD sed / gzip・zip 圧縮レベル6 / 検索のコールド・ウォームは uvp 1.6.3(2026-09-17 計測)、置換・圧縮・GUI は uvp 1.6.2 での実測 / 各計測の前に sudo purge、計測間にクールダウン
  • 3GB: OpenStreetMap 日本 XML から切り出した 3,032,812,644 byte。.uwvz は 251,829,224 byte(1/12.0)、gzip は 300,890,910 byte(1/10.1)
  • 検索の表は .uwvz 作成済みの状態。.uwvz の作成を含む1回目は、コールドで 4.64秒(rg 3.26秒)
  • 計測はすべて Mac(Apple M4 / メモリ32GB / 外付け USB SSD)。Windows・Linux(非力なノートPC・VMware 上)では傾向が変わる可能性があり、そちらは別途計測して記事にします

リンク

タイトルとURLをコピーしました