Dock Stay
ファイルシステム性能の差を理解する - /mnt/c vs ~ の使い方・オプション・サンプル

ファイルシステム性能の差を理解する - /mnt/c vs ~

WSL2 では `~/`(Linux 側 ext4)と `/mnt/c/`(Windows 側 NTFS)で IO 性能が 10 倍以上違うことがある。`9p` プロトコルを介した Windows FS アクセスが遅いため、作業ファイルの置き場所で体感が大きく変わる。

概念図

/mnt/c vs ~ diagram

構文

bash
df -T
mount | grep 9p

実例

ファイルシステム種別を確認

bash
df -T

9p マウント(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 動作)。diskpartOptimize-VHD で定期的に圧縮する
  • 2 世代以上遅いドライブ(外付け USB / ネットワークドライブ)を /mnt/* にマップすると 9p 越しでさらに遅くなる
  • Windows 側から見ると WSL2 のファイル更新が即時反映されないことがある。inotify もクロスで動かない

関連トピック