VPN共有上のVisual Studioが遅い理由:保存が往復になる仕組み
共有越しの編集は、保存・メニュー・変更追跡を往復に変えます。作業コピーをローカルに置き、履歴はたどるのではなく一つのオブジェクトとしてまとめて運びます。
ローカルディスクから一秒で開くソリューションが、トンネル越しの共有から開くと三十秒かかる。原因はトンネルそのものであることは少ない。変わるのは、ローカル呼び出しだった操作が同期的な往復になることであり、エディターはウィンドウが表示される前にそのうちのいくつかを実行する。以下の仕組みは、それぞれがなぜ高くつくのか、どれを削除できるのかを説明する。
ファイルを開いている間、エディターがしていること
変更追跡を有効にしたエディターは、開いているすべてのファイルに購読を張る。ローカルボリュームでは、その購読をネットワークを介さずファイルシステムが処理する。共有越しでは、通知モデルがSMB上で同じようには振る舞わないため、同じ機能がメタデータの繰り返し読み取りに劣化しうる。変更追跡を切るのは妥当な最初の実験である。トンネルに触れずに、要求の種類を丸ごと一つ減らせるからだ。
プロジェクトシステムは独自のトラフィックを追加する。ソリューションを読み込むとディレクトリを列挙し、プロジェクトファイルを読み、SDKやパッケージを調べることがあり、パスが遠隔にあるときはその調査のたびに往復が発生する。プロジェクトの多いソリューションではその回数が掛け算になり、ファイルサイズから想像されるより開く時間が速く伸びる。
メニューが現れる前に期限切れになるシェル参照
Windowsは、IDEとは何の関係もない第二の停止要因を持ち込む。エクスプローラーとそのシェル拡張は、コンテキストメニューを開くたびに、以前使ったプリンター、割り当て済みドライブ、ショートカットを再解決する。それらの対象がトンネルの届かないネットワーク上にあると、各解決はタイムアウトが切れるまで止まり、ようやくメニューが描画される。ファイル自体は普通に開くのに右クリックが数秒固まるのはそのためだ。
死んだ割り当てとプリンターキューを削除するか、実際にいるネットワークに存在するものだけを残す。同じ理屈は、最近使ったファイル一覧やピン留めしたフォルダーを含め、バックグラウンドでパスを解決するあらゆるものに当てはまる。
net use
Get-Printer | Select-Object Name, PortName
Measure-Command { Get-ChildItem \files\proj | Out-Null }
ローカルの作業コピーが勝つ理由
共有上で直接作業するのは、編集・ビルド・テストのループにとって最悪の構成だ。エディター、コンパイラー、バージョン管理クライアントがそれぞれ別々にそれらの遠隔ファイルを読むからである。どれも自分の往復を払い、ビルドはファイルごとに一度払う。リポジトリー経由でプッシュするローカルコピーは、小さな横断の洪水を一度の意図的な横断に置き換える。回線は良くなっていない。横断の回数が激減したのだ。
これはチューニングの練習ではなく構造の変更であり、トンネルの設定が効かないときに効くのはまさにそのためだ。しかも失敗の形がはっきりする。ローカルコピーでもビルドが遅いなら、共有は最初から問題ではなかった。
履歴を一つのオブジェクトとして移す
リポジトリー自体がトンネルを越えなければならないときは、履歴をたどるのではなく一つのオブジェクトとして送る。バンドルは一つのファイル、つまり一回の転送だが、何千もの緩いオブジェクトをたどるチェックアウトは何千回もの横断を要する。MercurialもGitもその形を支えている。
hg bundle --base 9f2c1a7e outgoing.hg
hg unbundle outgoing.hg
git bundle create repo.bundle main
git clone repo.bundle repo
基準リビジョンが肝心で、どれだけの履歴が旅するかを決める。すべてを束ねれば動くが回線を浪費し、最後の共通変更から束ねれば相手側に欠けている分だけが動く。
帯域を責める前に三つの操作を測る
三つを別々に測る。小さなファイルを一つ開く、ディレクトリーを一つ列挙する、保存を一回完了する。三つともファイル数に比例して遅いなら、費用は往復である。一つだけ詰まって他が平気なら、帯域ではなく到達できない資源に対するタイムアウトを疑う。実行のたびに機械がどのネットワークにいたかを記録する。別のプロファイルに再接続したノートPCは、試行の間に答えを変えうる。
そのうえで同じ三つをプロジェクトのローカルコピーに対して繰り返す。その差が共有の値段であり、回線を速くすれば直ると誰かが言ったときに示すべき数字だ。