しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Build 2023 で発表されて Windows 11 Insider Preview で利用可能になった Dev Drive を試した

先月の時点で Windows 11 Insider Preview の Dev Channel では利用可能になっていて、パフォーマンス面で気になっていた点を検証していたのですが、ようやく Dev Drive について簡単にまとめる気になりました。

Build 2023 ではオフライン限定の Dev Drive ディスカッション部屋もあったので覗いてきましたが、意外に注目されていない気配を感じました。Dev Drive については記事とドキュメントが地味に充実しているので、こちらを読んでおくと大体は理解できます。

記事とドキュメントは充実していますが、とりあえず試せる環境を作らないことには始まらないので、適当な Windows 11 マシンを Dev Channel に変更すると Dev Drive が作成可能になります。セットアップ方法は以下のドキュメントが分かりやすいです。

Dev Channel っぽく日本語と英語が混在した、ローカライズが不完全な画面が多いですが利用には問題ありません。VHD を利用するか、パーティションを作成するかを選べるようになっていますが、今回はパーティションを作成することにします。

パーティションを作成する方を選ぶと、既存パーティションのリサイズが出来るので、それを使って Dev Drive 用のパーティションを新しく確保します。この後に既存パーティションのサイズをいくつにリサイズするか入力する流れです。

リサイズしてしまえば、確保した領域を Dev Drive としてフォーマットしていきます。とりあえず D ドライブとしてマウントするのが一般的になる気がしています。

Dev Drive の作成が完了すると ReFS かつ Dev Drive として作成されたことがストレージの一覧から確認できるようになります。今回は 200GB を割り当ててあるはずです。

これで Dev Drive の作成が完了したので、Git のリポジトリなど一通りコピーすれば最低限の Dev Drive の恩恵に預かれます。更に Dev Drive を活用するためには、各言語のパッケージマネージャのキャッシュディレクトリを Dev Drive に移すことが推奨されています。

今回は NuGet と npm だけで試したので、以下の 2 つのコマンドを叩きこんでキャッシュの場所を Dev Drive に変更しておきました。事前にディレクトリを作っておいた方が安全です。

setx /M NUGET_PACKAGES D:\packages\nuget
setx /M npm_config_cache D:\packages\npm

これで Dev Drive を利用する準備も出来たので、適当に Nuxt 3 のプロジェクトを作成して npm ci の実行時間を確認してみました。npm i だとネットワーク周りに依存する部分が大きくなるので、キャッシュのある状態で npm ci を実行することでストレージ周りの違いを確認したいという目論見です。

以下が試してみた結果ですが、Dev Drive 上で実行した方が 2 倍近く早く完了しています。ちなみに Dev Drive ではない方では、キャッシュのディレクトリもデフォルトのままにしています。

Dev Drive は通常のドライブよりもパフォーマンスは改善されるのは確実のようですが、WSL 2 と比べるとまだ少し遅いようです。Node.js のアプリケーション開発は Dev Drive でも頑張れるレベルになってそうですが、WSL 2 の方が未だ優勢なのは変わらないようです。

次は NuGet 周りでの確認を行った結果ですが、正直なところ大きな違いは得られませんでした。用意できたプロジェクトがそこまで大きくないこともありますが、恐らく .NET Runtime などかなり規模の大きいプロジェクトぐらいで実感できる気がします。

ただし Dev Drive で利用可能な Copy-on-Write を MSBuild や .NET CLI で有効化すると、ビルド時にコピーされるアセンブリといった中間生成物などに効果的に作用するので、トータルでのストレージ使用量を大幅に改善できるようでした。有効化するには以下のドキュメントにあるように、専用の NuGet パッケージを追加する必要があります。

簡単な適用方法はドキュメントにもあるように Directory.Packages.Props を作成して CPM を有効化し、GlobalPackageReference として参照を追加する方法です。以下のような内容のファイルを作成すれば、ビルド時に Copy-on-Write が有効になります。

<Project>
  <ItemGroup>
    <GlobalPackageReference Include="Microsoft.Build.CopyOnWrite" Version="1.0.263" />
  </ItemGroup>
</Project>

そもそも CPM が気になる方は、以下のエントリで紹介しているのでこちらを参照してください。

パッケージを追加後、C# プロジェクトのビルドで Copy-on-Write を有効にするには、MSBuild や .NET CLI のパラメータとして /p:EnableCopyOnWriteWin=true を追加するだけです。プロパティの有無によってビルド後の消費ストレージサイズが 約 1GB から 20MB にまで大幅に削減されました。

内部では以下のリポジトリの実装が使われているようですが、今年リリース予定の .NET 8 には Linux と macOS 向けには組み込みの IO に Copy-on-Write の実装が入っているようです。

Windows 向けの Copy-on-Write 実装は含まれていないので、必要な場合はこのライブラリを利用できそうですが、やはり理想的には .NET の実装として透過的に利用できるようになっていて欲しいですね。