WSL2 開發容器與 9P 協議性能測試

tags: WSL2, Dev Container
category: Performance
description: WSL2 開發容器與 9P 協議性能測試
created_at: 2026/09/10 12:00:00

cover image


前言

先前在開發 Side Project 時,因為現今大多透過 AI 來協助開發,很容易不知不覺就產生了很多的程式碼以及測試程式(即使經過你的規劃,都在你的預期中),因此效能的問題也相較於以往更容易浮現。

只是在以前開發時通常是人工撰寫程式碼,即使有那麼一點的效能問題,也不會造成太大的困擾;而現今因為 AI 撰寫的速度非常快,很容易在短時間內產生大量程式碼,進而暴露出更多的效能瓶頸。

而在先前我開發的習慣就是讓程式碼可以隨處帶著跑,所以我都會在 Dev Container 中進行開發,這樣不論是在本地還是其他環境,都能保持一致的開發體驗。

然而我又是個很不喜歡汙染宿主環境的人,因此 Dev Container 對我來說是非常理想的選擇,我連 Docker Desktop 都不會在宿主環境中安裝,而是完全依賴 WSL2 來安裝 Docker。


事前準備

無,但如果你想測,可以先準備好 WSL2 與 Docker 環境,並確保 Dev Container 已正確配置。


以前怎麼做

  1. 打開桌面(或其他 Windows 檔案系統)的資料夾,然後建立一個新的專案資料夾。
  2. 用 VS Code 打開該資料夾,(假定已經安裝好 Dev Container 擴充功能)。
  3. Reopen in Container,將專案資料夾以 Dev Container 的方式打開。
  4. 開始在 Dev Container 中進行開發,所有的程式碼與依賴都會在容器內運行,而不會影響宿主環境。

這感覺是平常到不行的開發方式,但在效能上可能會有一些限制,特別是當專案變得越來越大時。


問題所在

在上述的開發方式中,所有的程式碼都存放在 Windows 的檔案系統中,然後透過 9P 協議掛載到 Dev Container 中。

而 Dev Container 實際上是跑在 WSL2 的虛擬化環境中,透過 9P 協議與宿主的 Windows 檔案系統進行交互。

這就意味著每次 Dev Container 需要讀寫程式碼時,都必須透過 9P 協議與宿主的 Windows 檔案系統進行通訊,這會帶來額外的延遲,特別是在大量小檔案操作時,效能瓶頸會更加明顯。

換句話說,當專案規模變大,檔案數量增加時,這種開發方式的效能問題會變得更加突出,可能會影響開發體驗。

這讓我想到很久以前開發時所錄製的影片,當 WSL 碰到稍微大一點的 Codebase

你是給不給儲存

只是當時沒有意識到是因為 WSL2 與 Windows 檔案系統之間的 9P 協議造成的性能瓶頸。

而今天剛好有空就來測試一下這個效能瓶頸,看看在不同的開發環境下,WSL2 與 9P 協議的影響到底有多大。

不過畢竟這種測試在各種不同機器上執行,結果可能會有所差異,因此僅供參考,只是大概了解效能瓶頸的情況就好。


測試設計

我請 AI 針對幾種常見的讀寫刪除檔案等操作設計了測試,並在不同的環境下進行了性能測試,最終得到以下結果。

9P 與 EXT4 的性能比較

其中 9P 指的就是 WSL2 與 Windows 檔案系統之間的通訊協議,而 EXT4 則是 WSL2 虛擬化環境內的原生檔案系統。

從圖中可以看出,9P 的性能明顯低於 EXT4,特別是在大量小檔案操作時,差距更加明顯。

9P 與 EXT4 的性能比率

這張圖展示了 9P 與 EXT4 的性能比率,可以更直觀地看到兩者之間的差距,在大檔案操作時,差距相對較小,但在大量小檔案操作時,9P 的性能劣勢依然明顯。

既然知道了這兩者之間的性能差距,那我們來看一個實際的例子,展示在開發過程中,9P 與 EXT4 的性能差異對開發體驗的影響。

實際開發中的性能差異

在這個測試中,我們準備了一份 package.json,長得像是下面這樣:

{
  "name": "fs-install-case",
  "private": true,
  "version": "0.0.0",
  "description": "實際案例:在 9p 與 ext4 上安裝同一棵依賴樹,把機制層的 per-op 數字接回真實的等待時間。刻意選純 JS 套件(無 node-gyp 編譯),讓時間差來自檔案操作而非 CPU。",
  "scripts": {
    "bench:ci": "npm ci --offline --ignore-scripts --no-audit --no-fund --legacy-peer-deps",
    "bench:prime": "npm install --package-lock-only --legacy-peer-deps && npm ci --ignore-scripts --no-audit --no-fund --legacy-peer-deps && rm -rf node_modules",
    "count": "printf 'files=%s dirs=%s\\n' \"$(find node_modules -type f | wc -l)\" \"$(find node_modules -type d | wc -l)\"",
    "bytes": "du -sh node_modules"
  },
  "devDependencies": {
    "@playwright/test": "^1",
    "@sveltejs/adapter-node": "^5",
    "@sveltejs/kit": "^2",
    "@types/node": "^22",
    "@typescript-eslint/eslint-plugin": "^8",
    "@typescript-eslint/parser": "^8",
    "@vitest/coverage-v8": "^2",
    "autoprefixer": "^10",
    "eslint": "^9",
    "eslint-plugin-svelte": "^2",
    "postcss": "^8",
    "prettier": "^3",
    "prettier-plugin-svelte": "^3",
    "svelte": "^5",
    "svelte-check": "^4",
    "tailwindcss": "^3",
    "typescript": "^5",
    "vite": "^6",
    "vitest": "^2"
  }
}

接著你可以透過一個 dev container 同時掛進 windows 與 wsl2 原生的檔案系統,然後在兩個環境中分別執行相同的安裝操作,觀察性能差異。

然後為了避免網路因素影響測試結果,我們先在 container 中將所有依賴下載到本地緩存,這樣在後續的安裝過程中就不需要再從網路下載依賴,從而保證測試結果的穩定性。

最終我們得到了以下的性能測試結果:

Dev Container 中 9P 與 EXT4 的性能比較 數字是我手動測試來的,只是圖是AI繪製的,所以可以對數字有信心

可以看到在 9p 掛載的檔案系統中,安裝依賴以及刪除 node_modules 的速度明顯慢於在 EXT4 原生檔案系統中,這也印證了前面測試中 9P 與 EXT4 的性能差距。


所以.. 原生檔案系統在哪

進入 wsl 的時候,我們會發現預設的目錄就是當前目錄,只是前面多了 /mnt/ 開頭,這就是 WSL2 對 Windows 檔案系統的掛載位置。換句話說,/mnt/c/Users/ 對應的就是 C:\Users\,這部分就是通過 9P 協議來進行讀寫的。

而 WSL2 的原生檔案系統則位於 / 根目錄下,通常是 ext4 格式的虛擬磁碟。這部分的讀寫操作不需要經過 9P 協議,因此性能要比掛載的 Windows 檔案系統高得多。

換句話說,如果希望在 WSL2 中獲得更好的檔案操作性能,應該盡量將專案放在 WSL2 的原生檔案系統中,而不是掛載的 Windows 檔案系統中。

因此,在使用 WSL2 進行開發時,將專案放在原生的 ext4 檔案系統中,可以顯著提升檔案操作的性能,從而改善開發體驗。

當然也可以透過 VM 然後 SSH 進入虛擬機中的原生檔案系統來進行開發,這樣同樣可以獲得接近原生的檔案操作性能。


懶人包

$ wsl
$ cd ~
$ mkdir my-project
$ code my-project

然後後面就都一樣了。


檢查

可以透過以下命令來檢查是否正確的使用到 WSL2 的原生檔案系統。

$ grep $(pwd) /proc/mounts

如果輸出中顯示的掛載點是 / 開頭的路徑,則說明專案位於 WSL2 的原生檔案系統中;如果是 /mnt/ 開頭的路徑,則說明專案位於掛載的 Windows 檔案系統中。

也可以看掛載點後面的檔案系統類型,如果是 9p,則說明是掛載的 Windows 檔案系統;如果是 ext4,則說明是 WSL2 的原生檔案系統。


補充資料

WSL2 性能考量


結論

總結來說,9P 協議雖然方便了 WSL2 與 Windows 之間的檔案共享,也解決了跨系統檔案訪問的問題,但在性能上仍然存在明顯的劣勢。因此,對於需要頻繁進行檔案操作的開發場景,將專案放在 WSL2 的原生 ext4 檔案系統中,仍然是獲得最佳性能的選擇。




最後更新時間: 2026年09月10日.