🔥

WSL2 で PATH に Windows 側のパスがあると man の起動速度が遅くなる

に公開

WSL2 環境で man を実行する際、PATH に /mnt/ で始まる Windows 側のパスが含まれていると遅くなる。
WSL2 ではデフォルトで PATH に /mnt/ で始まる Windows 側のパスが追加される。

PATH に Windows 側のパスが含まれている場合:

$ time man -k apropos
apropos (1)          - search the manual page names and descriptions

________________________________________________________
Executed in    1.23 secs      fish           external
   usr time   28.20 millis    2.29 millis   25.91 millis
   sys time   77.99 millis    2.71 millis   75.28 millis

PATH に Windows 側のパスが含まれていない場合:

$ time PATH=(string split : $PATH | rg -v '^\/mnt\/' | string join :) man -k apropos
apropos (1)          - search the manual page names and descriptions

________________________________________________________
Executed in  113.37 millis    fish           external
   usr time   37.45 millis    0.60 millis   36.85 millis
   sys time   22.28 millis    5.46 millis   16.82 millis

試した環境は WSL2 + Ubuntu 24.04 + fish 4.0.2 で、PATH には Windows 側のパスが18個含まれている。

$ string split : $PATH | rg '^\/mnt\/' | wc -l
18

原因調査

manpath のマニュアルの SEARCH PATH セクションに次のように書いてある。

By default, man-db examines the user's $PATH. For each path_element found there, it adds manpath_element to the search path.

If there is no MANPATH_MAP line in the configuration file for a given path_element, then it adds all of path_element/../man, path_element/man, path_element/../share/man, and path_element/share/man that exist as directories to the search path.

PATH の各要素(path_element)のうち設定ファイルの MANPATH_MAP に該当するものがない場合は path_element/../man、path_element/man、path_element/../share/man、path_element/share/man がマニュアルの探索パスに追加される。

PATH に Windows 側のパスが含まれていると、パフォーマンスの劣る Windows 側の複数のパスを探索することで man の起動が遅くなっていると推測される。

対策

Windows 側の実行ファイルを WSL2 側から呼び出すことがないなら設定(/etc/wsl.conf)で追加されないようにすればよい。

[interop]
appendWindowsPath = false

詳細はこちらを参照。
この設定変更の反映には WSL2 の再起動が必要。

man を実行する場合だけ PATH から Windows 側のパスを除外するにはシェルの関数でラップして一時的に PATH を変更すればよい。

fish shell の例。

function man
    PATH=(string split : $PATH | rg -v '^\/mnt\/' | string join :) command man $argv
end

Discussion