ファイルシステム性能の差を理解する - /mnt/c vs ~
WSL2 では `~/`(Linux 側 ext4)と `/mnt/c/`(Windows 側 NTFS)で IO 性能が 10 倍以上違うことがある。`9p` プロトコルを介した Windows FS アクセスが遅いため、作業ファイルの置き場所で体感が大きく変わる。
概念図
構文
bash
df -T
mount | grep 9p実例
ファイルシステム種別を確認
bash
df -T9p マウント(Windows 側 FS)を洗い出す
bash
mount | grep 9p実測で IO 差を比較
bash
hyperfine 'ls -l ~/src' 'ls -l /mnt/c/src'概要
WSL2 では、どこにファイルを置くかで IO 性能が大きく変わります。
2 つの領域を対比して整理します。
- WSL2 側(
~/配下の ext4)- VHDX 上の ext4 をネイティブにマウントしており、Linux として素直な性能が出る
git status/npm install/findなど多数ファイルを舐める処理が速い
- Windows 側(
/mnt/c/配下の NTFS)9pというネットワークファイルシステムプロトコル経由でマウントされる- 1 ファイル操作ごとに Windows カーネルへ往復し、メタデータ操作が特に遅い
- 多数ファイル処理では
~/側と比べて 5〜20 倍の時間差になる
WSL1 ではむしろ Windows 側 FS の方が速かったため、WSL1 から移行してきたユーザーがこの違いで戸惑うケースが多いです。
典型的な用途
- Node.js / Python / Ruby のプロジェクトで大量の小さなファイルを扱う
- Git リポジトリに対する status / diff / checkout
- ビルドツール(webpack、Vite、tsc、gradle 等)の差分検出
- Docker の bind mount を使った開発時ホットリロード
- AV / EDR がすべての IO をスキャンする環境での IO スローダウン回避
コマンド例
# 今どこに居るかを確認
pwd
# /home/alice/src/myapp ← WSL2 側(速い)
# /mnt/c/Users/Alice/... ← Windows 側(遅い)
# マウント一覧
mount | grep 9p
# C:\ on /mnt/c type 9p (rw,...,aname=drvfs;path=C:;uid=1000;gid=1000;...)
# 簡易ベンチ(hyperfine がなければ time でも可)
cd ~/tmpbench && git clone https://github.com/nodejs/node.git
time (cd ~/tmpbench/node && git status)
# ここでは速い
cp -r ~/tmpbench/node /mnt/c/Users/$USER/tmpbench-win
time (cd /mnt/c/Users/$USER/tmpbench-win/node && git status)
# 明らかに遅い
ベストプラクティス
- ソースコード・node_modules・venv などの「開発中によく触るファイル群」は必ず WSL2 側に置く
- VS Code は WSL 拡張経由で
~/...を開く。\\wsl$\Ubuntu\...経由でも可能だが明示的に WSL 側で開いたほうが早い - Docker の bind mount は WSL2 側のパスを使う。
/mnt/c/...をマウントするとコンテナ内でも 9p 経由になり 2 段で遅くなる - Windows 側でしか扱えないファイル(ExplorerFileManager で直接編集が必要なもの)は
\\wsl$\Ubuntu\home\...として読みに行く - Windows Defender で WSL2 の VHDX とプロジェクトディレクトリを除外設定する(パフォーマンス重視の場合)
注意点
\\wsl$\経由で Windows 側からアクセスする場合、ファイル属性(実行ビット等)が直感的に扱えない/mnt/cの大文字小文字区別は NTFS に従い、既定では区別されない。Linux 前提のコードが混乱することがある- WSL2 の VHDX は使い続けると縮まない(sparse 動作)。
diskpartやOptimize-VHDで定期的に圧縮する - 2 世代以上遅いドライブ(外付け USB / ネットワークドライブ)を
/mnt/*にマップすると 9p 越しでさらに遅くなる - Windows 側から見ると WSL2 のファイル更新が即時反映されないことがある。
inotifyもクロスで動かない
関連トピック
WSL2- Windows Subsystem for Linux の第 2 世代。Hyper-V 技術を基盤にした軽量 VM 上で本物の Linux カーネルを動かす方式で、WSL1 のエミュレーションとは根本的に別物。Docker Desktop の標準バックエンドでもある。 Docker Desktop- Docker Desktop for Windows は WSL2 をバックエンドとしてコンテナを動かす構成。`docker-desktop` 専用ディストリに dockerd を常駐させ、ユーザーのディストリからは統合機能で透過的に使える。 systemd- かつて WSL2 は独自 init を使っており systemd が動かなかったが、2022 年以降の WSL でネイティブサポートされた。`/etc/wsl.conf` に `systemd=true` を書き、`wsl --shutdown` で再起動するだけで有効になる。 