WSLからWindows側のファイルを操作すると遅い。AWS CLIを使った操作でどのくらい差が出るのか実験してみた。
実験内容
シナリオ
- Windows側にあるフォルダをS3に同期する
- 実体はNTFSフォーマットされた単一のSATA SSD上にある
- 同期対象ファイル数は2.3万個、合計ファイルサイズは16GiB
- ローカルとS3の差分を検出し不足と過剰をレポートさせる
- 同一条件で何度も比較するため、実際にはアップロードしないドライランモードを使う
- 一度ドライランが終わったら間を置かず再実行し、結果が変わるかを見る
環境
- WSL側
- aws-cli/2.15.24 Python/3.11.6
- Ubuntu 20.04.6 LTS / WSL 2.2.4.0
- Ubuntu 上の bash から /mnt/d/syncdir に対して aws s3 sync する
- Windows側
- aws-cli/2.15.33 Python/3.11.8
- Windows 11 Home 24H2
- cmd.exe から D:\syncdir に対して aws s3 sync する
初回実行の結果
- WSL:5分22秒
- Windows:3分04秒
WSLで実行すると単純に所要時間が75%ほど増えることがわかった。わかりやすく遅い。
当然ながらあらゆるワークロードでこの差が出るわけでもない。
予想される傾向としては:
- 両環境の差は同期対象のファイル数に線形に依存する
- たとえば少数の巨大ファイルを同期するような用途であれば差はわずかになる
- 物理のストレージが高速であるほど差が開く
- 今回であればSATAではなくNVMe SSDで実験すればより差が顕著だったと思われる
- (WSLはファイル操作1件ごとに固定値のオーバーヘッドが載るという前提に立っている)
2回目の実行結果
面白いことになった。
- WSL:5分12秒
- Windows:13秒(!)
Windows側の高速化のされっぷりがおかしいことになっている。なんと10倍以上。
明らかに真面目に数えておらず、何らかのキャッシュがあるのだと思われるが、WSL側はほとんど高速化できていないことからキャッシュの有無だけが理由ではなさそうだ。
もしかしたらNTFSのディレクトリメタデータみたいなのを読んでラクできる仕組みがあるのかもしれない。
まとめ:WSLは便利だけど特定用途ではcmdに戻るべき
普段からコマンド実行環境をLinux側に寄せていると aws-cli なども何も考えずにWSL側にインストールしてしまうが、用途によってはcmdで叩いた方が大幅に速くなるとわかった。
とくに2回目以降のキャッシュの効き方は劇的だった。今回見出された5分差は今後もずっと維持されたままになると思われる。実行するたびに5分違うとなれば無視はできない。
他にもローカル開発でJestで単体テスト回したり、Webpackでバンドル作ったりするとき顕著に差が出ることを確認している。
「WSLは便利だが、ファイルIOが多いワークロードでは不利」「秒オーダーの時間がかかるようならcmdへ移行検討」は覚えておきたい。
コメント