NGen による起動時のパフォーマンスの向上
Note
EF6 以降のみ - このページで説明する機能、API などは、Entity Framework 6 で導入されました。 以前のバージョンを使用している場合、一部またはすべての情報は適用されません。
.NET Framework では、アプリケーションの起動を高速化したり、場合によっては使用するメモリを少なくする手段として、マネージド アプリケーションとライブラリのネイティブ イメージの生成がサポートされています。 ネイティブ イメージは、アプリケーションの実行前に、マネージド コード アセンブリをネイティブ マシン命令を含むファイルに変換することによって作成されます。これにより、.NET JIT (Just-In-Time) コンパイラは、アプリケーションの実行時にネイティブ命令を生成する必要がなくなります。
バージョン 6 より前では、EF ランタイムのコア ライブラリは .NET Framework の一部であり、ネイティブ イメージはそれらから自動的に生成されました。 バージョン 6 以降では、EF ランタイム全体が EntityFramework NuGet パッケージに結合されています。 同様の結果を得るには、NGen.exe コマンド ライン ツールを使用してネイティブ イメージを生成しなければならなくなりました。
経験的な観察によれば、EF ランタイム アセンブリのネイティブ イメージによって、アプリケーション起動時間が 1 秒から 3 秒ほど削減できることがわかりました。
NGen.exe の使用方法
NGen.exe ツールの最も基本的な機能は、アセンブリとそのすべての直接の依存関係のネイティブ イメージを "インストール" する (つまり、ディスクに作成し、保存する) ことです。 これを実現する方法を次に示します。
管理者としてコマンド プロンプト ウィンドウを開きます。
現在の作業ディレクトリを、ネイティブ イメージを生成するアセンブリの場所に変更します。
cd <*Assemblies location*>
オペレーティング システムとアプリケーションの構成によっては、32 ビット アーキテクチャ、64 ビット アーキテクチャ、またはその両方のネイティブ イメージを生成することが必要になる場合があります。
32 ビットの場合は、次のように実行します。
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install <Assembly name>
64 ビットの場合は、次のように実行します。
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install <Assembly name>
ヒント
正しくないアーキテクチャのネイティブ イメージを生成することは、非常に一般的な間違いです。 確信が持てない場合は、マシンにインストールされているオペレーティング システムに適用されるすべてのアーキテクチャのネイティブ イメージを生成できます。
また、NGen.exe は、インストールされているネイティブ イメージのアンインストールと表示、複数のイメージの生成のキューなど、他の機能もサポートしています。使用法の詳細については、NGen.exe のドキュメントを参照してください。
どのようなときに NGen.exe を使用するか
EF バージョン 6 以降に基づくアプリケーションのどのアセンブリのネイティブ イメージを生成するかを決定する際には、次のオプションを考慮する必要があります。
- メイン EF ランタイム アセンブリである EntityFramework.dll: 一般的な EF ベースのアプリケーションは、起動時またはデータベースへの最初のアクセス時に、このアセンブリの大量のコードを実行します。 そのため、このアセンブリのネイティブ イメージを作成すると、起動時のパフォーマンスで最大の効果が得られます。
- アプリケーションによって使用される任意の EF プロバイダー アセンブリ: これらのネイティブ イメージを生成した場合も、起動時間に多少の効果が得られます。 たとえば、アプリケーションで SQL Server 用の EF プロバイダーが使用されている場合は、EntityFramework.SqlServer.dll のネイティブ イメージを生成できます。
- アプリケーションのアセンブリとその他の依存関係: NGen.exe のドキュメントでは、ネイティブ イメージを生成するアセンブリを選択するための一般的な条件、セキュリティ上のネイティブ イメージの影響、"ハード バインディング" などの高度なオプション、デバッグとプロファイリングでネイティブ イメージを使用するシナリオなどについて説明されています。
ヒント
アプリケーションの起動時のパフォーマンスと全体的なパフォーマンスの両方で、ネイティブ イメージを使用した場合の影響を慎重に測定し、実際の要件と比較してください。 一般に、ネイティブ イメージは起動時のパフォーマンスの向上に役立ち、場合によってはメモリ使用量が削減されますが、すべてのシナリオで同等のメリットが得られるわけではありません。 たとえば、定常状態の実行の場合 (つまり、アプリケーションによって使用されるすべてのメソッドが少なくとも 1 回呼び出された場合)、JIT コンパイラによって生成されるコードが実際にネイティブ イメージよりもいくらか優れたパフォーマンスを示すことがあります。
開発用マシンでの NGen.exe の使用
開発中は、.NET JIT コンパイラによって、頻繁に変更されるコードに対する全体的なトレードオフが最適になります。 EF ランタイム アセンブリなど、コンパイルされる依存関係のネイティブ イメージを生成すると、各実行の始めの数秒が削減され、開発とテストの時間を短縮できます。
EF ランタイム アセンブリを探すための最適な場所は、ソリューションの NuGet パッケージの場所です。 たとえば、EF 6.0.2 と SQL Server を使用し、.NET 4.5 以降をターゲットとするアプリケーションの場合は、コマンド プロンプト ウィンドウで次のように入力できます (管理者として開いてください)。
cd <Solution directory>\packages\EntityFramework.6.0.2\lib\net45
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install EntityFramework.SqlServer.dll
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install EntityFramework.SqlServer.dll
Note
これは、SQL Server 用の EF プロバイダーのネイティブ イメージをインストールすると、メイン EF ランタイム アセンブリのネイティブ イメージも既定でインストールされるという事実を利用しています。 これが機能するのは、EntityFramework.dll が、同じディレクトリにある EntityFramework.SqlServer.dll アセンブリの直接の依存関係であることを NGen.exe が検出できるためです。
セットアップ中のネイティブ イメージの作成
WiX Toolkit では、この攻略ガイドで説明されているように、セットアップ中にマネージド アセンブリのネイティブ イメージの生成をキューで処理する機能がサポートされています。 別の方法として、NGen.exe コマンドを実行するカスタム セットアップ タスクを作成することもできます。
EF のためにネイティブ イメージが使用されていることの確認
特定のアプリケーションがネイティブ アセンブリを使用していることを確認するには、拡張子が ".ni.dll" または ".ni.exe" である読み込み済みアセンブリを探します。 たとえば、EF のメイン ランタイム アセンブリのネイティブ イメージは、EntityFramework.ni.dll という名前になります。 プロセスの読み込まれた .NET アセンブリを検査する簡単な方法は、プロセス エクスプローラーを使用することです。
その他の注意点
アセンブリのネイティブ イメージを作成することを、アセンブリを GAC (Global Assembly Cache) に登録することと混同しないようにしてください。 NGen.exe を使用すると、GAC にないアセンブリのイメージを作成できます。実際には、特定のバージョンの EF を使用する複数のアプリケーションが、同じネイティブ イメージを共有できます。 Windows 8 では GAC に配置されたアセンブリのネイティブ イメージを自動的に作成できますが、EF ランタイムはアプリケーションと共にデプロイされるように最適化されており、GAC への登録はお勧めしません。これは、アセンブリ解決やその他の面でのアプリケーションへのサービスに悪影響を及ぼすためです。
.NET