0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ripgrep は no-mmap で 2.9倍 速くなる — 既定の mmap 読みと 50GB・3OS で比べた

0
Posted at

結論

51.25GB の1本のファイルを検索するとき、rg --no-mmap が既定より速くなることがあります。
ただし、OS と検索の中身で答えが割れます。

50GB・rg・コールド 既定(--mmap --no-mmap 効き目
Windows 11・固定文字列 83.74秒 68.50秒 1.22倍 速い
Windows 11・正規表現+除外 282.84秒 97.83秒 2.89倍 速い
macOS・固定文字列 55.38秒 55.70秒 変わらない
macOS・正規表現+除外 59.40秒 58.47秒 変わらない
Linux VM(8GB)・固定文字列 約83秒 約100秒 約1.2倍 遅い
Linux VM(8GB)・正規表現+除外 約172秒 約105秒 1.64倍 速い

6通りのうち 3つで速くなり、2つで変わらず、1つで遅くなりました。

  • macOS: 何もしなくてよい。既定で最善が出ている
  • Windows: 51GB では既定が不利。とくに重い検索で3倍近く損をする
  • Linux: 検索の中身で逆転する。軽い検索は既定、重い検索は --no-mmap

測った条件

  • ファイル: OpenStreetMap 日本の XML、51,254,526,392 バイトの1本
  • 検索1: rg -n -F '東京' <file> — 94,979 ヒット
  • 検索2: rg -n -v '^ +<' <file> — 3 ヒット
  • ripgrep 15.2.0(Linux のみ 15.1.0)
  • 毎回キャッシュを破棄して10秒待ってからコールド計測
    (macOS sudo purge / Linux drop_caches / Windows は RAMMap -Et を管理者権限で)
  • 出力の行数が --mmap--no-mmap で一致することを毎回確認
機械
macOS Apple M4 / 32GB / 外付け USB SSD
Windows 11 Core i7-1165G7(4C8T・15W級)/ 15.6GB / Intel Optane H20 with SSD
Linux 上記 Mac 上の VMware・仮想2コア / 8GB

秒数は機械をまたいで比較しないでください。 見るのは同じ機械の中の2本です。

犯人はディスクでも CPU でもなかった

Windows で最初に疑ったのは、ファイルの置き場所と断片化でした。違いました。
ツールを通さずに同じ 3GiB を読むと、51GB ファイルの先頭 1159 MB/s・中間 1134 MB/s・末尾 1168 MB/s
このディスクは素で 1.1GB/s 出るので、51.25GB を読むだけなら約45秒が下限です。

次に疑ったのが CPU の熱だれ。15W の薄型ノートなら5分の連続負荷で落ちてもおかしくない。これも違いました。
CurrentClockSpeed は開始前も終了後も 2803MHz。3GB の同じ検索を5回続けても 7.1秒前後で一定です。

残ったのが読み方でした。--no-mmap を付けると 282.84秒が 97.83秒になります。

なぜこうなるのか(ここからは推測)

メモリマップは、ページに触るたびに OS がディスクから読み込む仕組みです。
ファイルがメモリに収まっていれば、コピーが1回減るぶん効率的です。

収まらないときが問題で、51.25GB は Windows 機の 15.6GB にも Mac の 32GB にも収まりません。
読んでいるあいだ中、ページを入れては捨てを繰り返すことになります。
この出し入れの代償が OS によって違うのだろう、というのが現時点の見立てです。

ただし測定結果から逆算した説明で、確かめたわけではありません。
とくに Linux が「軽い検索だと既定が速く、重い検索だと --no-mmap が速い」と逆転する理由は説明できていません。
ご存じの方がいたら教えてください。

自分の環境で確かめる

# 1回目(既定)
rg --mmap -n -F '探す語' huge.log > /dev/null

# キャッシュを捨てる
#   macOS : sudo purge
#   Linux : sync && sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
#   Windows: RAMMap64.exe -accepteula -Et  (管理者権限)

# 2回目
rg --no-mmap -n -F '探す語' huge.log > /dev/null

キャッシュを捨てずに測ると、2回目が速く出るだけで何も分かりません。 ここは省かないでください。
そして両方で出力の行数が一致することを確かめてください。違っていたら、測り方のほうが違っています。

付記

この計測は、自分が作っている巨大ファイル用の CLI(uvf)を ripgrep と比べる過程で出てきたものです。
uvf は mmap を使わず順次読みなので3環境で挙動が同じですが、裏を返せば Linux で mmap が有利な場面を取りこぼしていることになります。
そこは宿題です。

条件と全データはこちらにまとめてあります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?