UwViewで51GB・8.9億行の実データ(OSM日本)を開いてみた — 「お詫び:2億行は嘘でした」

技術解説

先日、大容量テキストビューア「UwView」をGitHubで公開した記事を書きました。「最大2億行クラスを高速に閲覧できる」とうたっていますが、これまでの実測は行番号を振っただけの合成データでのものでした。「実際の、しかも桁違いに大きい実データではどうなのか」——今回はそれを確かめます。

題材に選んだのは OpenStreetMap(OSM)日本全体のデータをXML化したファイル。結果として 51GB・約8.9億行 という、うたい文句の「2億行」を4倍以上も上回る規模になりました。

リポジトリ: amru195704/UwView(PolyForm Internal Use License 1.0.0)


テストデータの作り方 — OSM日本を51GBのXMLに

OSMの日本データは Geofabrik から配布されています。配布形式はバイナリの .osm.pbf(約2.3GB)なので、これを osmium-tool でXMLテキスト(.osm)に展開します。

# pbf(2.3GB・バイナリ)を取得
curl -L -o japan-latest.osm.pbf \
  https://download.geofabrik.de/asia/japan-latest.osm.pbf

# osmium で XML(テキスト)に変換 → 51GB・8.9億行
osmium cat japan-latest.osm.pbf -o japan-latest.osm

できあがったファイルはこんな中身のUTF-8テキストです。緯度経度を持つ <node> 要素が延々と並びます。

<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.6" generator="osmium/1.19.1">
  <bounds minlat="20.08228" minlon="122.5607" maxlat="45.815403" maxlon="154.4709"/>
  <node id="31236558" version="5" timestamp="2020-06-27T07:40:04Z" lat="35.635073" lon="139.768101"/>
  ...

wc -l で数えると 892,239,125行。まさに「エディタでは絶対に開けない」領域のファイルです。


実測結果(51GB・892,239,125行・Apple Silicon Mac・外付けSSD)

UwViewに同梱のベンチハーネス(UwView.Bench)で計測しました。

項目 実測値
ファイルサイズ 51,254,526,392 バイト(約48 GiB)
open+文字コード判定 12 ms
ページモード表示(先頭50行+50%位置50行) 3 ms
索引構築(1回の順次読み) 172.8秒(283 MB/s)
総行数 892,239,125wc -l と完全一致)
チェックポイント数(索引) 3,485,310件 ≒ 26.6 MB
マネージヒープ増加 33.3 MB
GetLineランダム1000回 平均 1.28 ms/p99 3.0 ms/最大 5.7 ms
先頭行取得 <?xml version='1.0' encoding='UTF-8'?>(2.9 ms)
末尾(8.9億行目)ジャンプ </osm>0.006 ms
文字コード切替 3.4 ms(索引再構築なし)
WorkingSet 12,083 MB(mmapページ含む・OSが回収可能)

「2億行の壁」は問題なく越えた

今回いちばん確かめたかったのは、うたい文句の2億行を超えても破綻しないかでした。結論から言うと、問題ありませんでした。

  • 総行数が正確:UwViewが数えた 892,239,125 は、wc -l の結果と1行の狂いもなく一致しました。
  • 末尾ジャンプが即時:8.9億行目(最終行 </osm>)へのジャンプは 0.006 ms。索引さえできていれば、ファイルのどこへ飛んでも一瞬です。
  • メモリは据え置き:51GBのファイルに対して、常駐するのは索引26.6MB+マネージヒープ33MB程度。ファイル本体はメモリに載せません。

UwViewは行番号を long(64bit整数)で通していますが、そもそも8.9億は int の上限(約21.4億)にも収まる範囲です。設計上、行数がここでボトルネックになることはありません。

なお表の「WorkingSet 12GB」は大きく見えますが、これはmmapで触れたファイルページのキャッシュで、OSがメモリ圧に応じて随時回収する非常駐領域です。アプリが確保しているメモリではありません。


合成データとの差 — 正直なところ

以前の合成2億行データと、今回の実データ8.9億行を並べてみます。

項目 合成2億行(5.1GB) 実データ8.9億行(51GB)
索引構築速度 538 MB/s 283 MB/s
GetLineランダム(平均) 0.005 ms 1.28 ms
末尾ジャンプ 0.003 ms 0.006 ms
索引サイズ 6.0 MB 26.6 MB

GetLineが合成データより遅い(0.005ms → 1.28ms)のは正直に触れておきます。理由は3つあります。

  1. 外付けSSDのランダム読みが律速(内蔵SSDならもっと速い)。
  2. 実XMLは行長がまちまちで、キャッシュ効率が合成データより悪い。
  3. 51GBはメモリに載りきらず(WorkingSet 12GB)、多くの読みが実ディスクI/Oになる。

とはいえ「ミリ秒級」であることに変わりはなく、スクロールや行ジャンプの体感は十分実用的です。索引構築の283MB/sも、51GBを1回だけ順次に読む処理で、こちらは完全にストレージの速度で決まります。


開いた瞬間から見える — ページモードの強み

もうひとつ強調したいのは、索引構築(約3分)を待たずに閲覧を始められる点です。今回も、開いてから文字コード判定まで12ms、最初の1画面の表示は3msでした。51GBのファイルであっても、less で巨大ファイルを開いた瞬間のように、まず「バイト位置ベースのページモード」で即座に中身が見え、裏で索引ができあがったら「行番号ベースの行モード」へ静かに昇格します。

「巨大ファイルを開く」と身構える必要がなく、ダブルクリックした瞬間から中身が見える——これがUwViewのいちばん伝えたい体験です。


まとめ

  • OSM日本全体をXML化した 51GB・8.9億行 の実データを、UwViewで開いて検証した。
  • うたい文句の「2億行」を4倍以上超えても破綻せず、総行数は wc -l と完全一致、末尾(8.9億行目)ジャンプも 0.006 ms。
  • 常駐メモリは索引26.6MB+ヒープ33MB程度。ファイル本体は非常駐。
  • 開いた瞬間(12ms/3ms)からページモードで閲覧でき、索引は裏で構築(約3分・283MB/s=ストレージ律速)。
  • GetLineは実データで平均1.3ms(合成0.005msより遅いが、外付けSSD・行長不均一・キャッシュ外の実I/Oが理由)。それでもミリ秒級で実用的。

「最大2億行」はあくまで目安で、実際には行数よりストレージ容量が先に効くことが実データで確認できました。
実際問題として8.9億行もあると、行インデックス作成に三分程度かかり検索してもなかなか結果が出ません。実用は2億行ぐらいでしょう。
理論的には64ビットなので、。。。。怖くてテストできません。

関連記事

出典

  • amru195704/UwView(GitHub) https://github.com/amru195704/UwView
  • OpenStreetMap Japan extract(Geofabrik) https://download.geofabrik.de/asia/japan.html
  • osmium-tool https://osmcode.org/osmium-tool/

上位版:UwView Pro(発売中・全OS対応:Windows/macOS/Linux)

「巨大ファイルをいつでも瞬時に表示・検索、索引を保存して2回目以降は行番号付きで瞬時に開く・検索が最大約9倍・ログを約1/9で保管してそのまま開ける」商用版です。買い切り $129 / 月額 $9。
→ https://uvp.y42u.net/pro/
(UwView / UwView Pro は、初回でも開いた瞬間からファイル全体を閲覧・検索できます。索引はバックグラウンドで作成し、完成後に行番号を表示。UwView Pro は索引と圧縮を保存するので、2回目以降は行番号付きで瞬時に開けます。他ツールは索引が終わるまで先頭しか見えませんが、UwView は1回目から全体を瞬時に閲覧・検索できます)


開発者より: アプリ・Kindle本・オープンソースの一覧は GitHub: amru195704 にまとめています。


お願い
本記事の情報は参考目的で掲載しており、正確性・完全性を保証するものではありません。誤記・不正確な情報がございましたら、コメント欄よりご指摘いただければ、確認のうえ修正いたします。

コメント

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