次の方法で共有


ReadyToRun コンパイル

.NET アプリケーションの起動時間と待機時間は、アプリケーション アセンブリを ReadyToRun (R2R) 形式でコンパイルすることで改善できます。 R2R は、事前コンパイル (AOT) の形式です。

R2R バイナリでは、アプリケーションの読み込み時に Just-In-Time (JIT) コンパイラで行う必要がある作業量を減らすことにより、起動時のパフォーマンスが向上します。 バイナリには、JIT で生成されるものと似たネイティブ コードが含まれます。 ただし、R2R バイナリは、中間言語 (IL) コード (一部のシナリオでまだ必要です) と同じコードのネイティブ バージョンの両方が含まれるため、大きくなります。 R2R は、Linux x64 や Windows x64 などの特定のランタイム環境 (RID) を対象とするアプリを発行する場合にのみ使用できます。

プロジェクトを ReadyToRun としてコンパイルするには、PublishReadyToRun プロパティを true に設定してアプリケーションを発行する必要があります。

ReadyToRun としてアプリを発行するには、次の 2 つの方法があります。

  1. dotnet publish コマンドに直接 PublishReadyToRun フラグを指定します。 詳細については 、dotnet publish を参照してください。

    dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true
    
  2. プロジェクトのプロパティを指定します。

    • <PublishReadyToRun>設定をプロジェクトに追加します。
    <PropertyGroup>
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    
    • 特別なパラメーターを指定せずにアプリケーションを発行します。
    dotnet publish -c Release -r win-x64
    

ReadyToRun 機能を使用した場合の影響

事前コンパイルでは、アプリケーションのパフォーマンスに複雑なパフォーマンスの影響があり、予測が困難な場合があります。 一般に、アセンブリのサイズは 2 ~ 3 倍に大きくなります。 ファイルの物理サイズが増加すると、ディスクからアセンブリを読み込むパフォーマンスが低下し、プロセスのワーキング セットが増加する可能性があります。 ただし、その代わりに、実行時にコンパイルされるメソッドの数は通常、大幅に削減されます。 その結果、大量のコードを持つほとんどのアプリケーションは、ReadyToRun を有効にすることで大きなパフォーマンス上の利点を得られます。 .NET ランタイム ライブラリは既に ReadyToRun でプリコンパイルされているため、コードの量が少ないアプリケーションでは、ReadyToRun を有効にした場合の大幅な改善は発生しない可能性があります。

ここで説明するスタートアップの改善は、アプリケーションの起動だけでなく、アプリケーション内の任意のコードの最初の使用にも適用されます。 たとえば、ReadyToRun を使用して、ASP.NET アプリケーションで Web API を初めて使用する場合の応答待機時間を短縮できます。

階層化コンパイルとの対話

事前に生成されたコードは、JIT によって生成されるコードほど高度に最適化されていません。 この問題に対処するために、階層化コンパイルでは、一般的に使用される ReadyToRun メソッドが JIT で生成されたメソッドに置き換えられます。

プリコンパイル済みアセンブリのセットはどのように選択されますか?

SDK は、アプリケーションと共に配布されるアセンブリをプリコンパイルします。 自己完結型アプリケーションの場合、このアセンブリのセットにはフレームワークが含まれます。 C++/CLI バイナリは ReadyToRun コンパイルの対象ではありません。

ReadyToRun 処理から特定のアセンブリを除外するには、 <PublishReadyToRunExclude> リストを使用します。

<ItemGroup>
  <PublishReadyToRunExclude Include="Contoso.Example.dll" />
</ItemGroup>

プリコンパイルする一連のメソッドはどのように選択されますか?

コンパイラは、可能な限り多くのメソッドを事前コンパイルしようとします。 ただし、さまざまな理由から、ReadyToRun 機能を使用しても JIT が実行されないことは想定されていません。 このような理由には、次のものが含まれますが、これらに限定されるわけではありません。

  • 個別のアセンブリで定義されているジェネリック型の使用。
  • ネイティブ コードとの相互運用。
  • コンパイラが証明できないハードウェア組み込みの使用は、ターゲット コンピューターで安全に使用できます。
  • 特定の異常な IL パターン。
  • リフレクションまたは LINQ を使用した動的メソッドの作成。

プロファイラーで使用するシンボルの生成

ReadyToRun を使用してアプリケーションをコンパイルする場合、プロファイラーでは、生成された ReadyToRun ファイルを調べるためのシンボルが必要になる場合があります。 シンボル生成を有効にするには、 <PublishReadyToRunEmitSymbols> プロパティを指定します。

<PropertyGroup>
  <PublishReadyToRunEmitSymbols>true</PublishReadyToRunEmitSymbols>
</PropertyGroup>

これらのシンボルは発行ディレクトリに配置され、Windows の場合はファイル拡張子が .ni.pdb になり、Linux の場合はファイル拡張子が .r2rmap になります。 これらのファイルは通常、エンド カスタマーに再配布されるのではなく、通常はシンボル サーバーに格納されます。 一般に、これらのシンボルは、アプリケーションの起動に関連するパフォーマンスの問題のデバッグに役立ちます。 階層コンパイル では、ReadyToRun で生成されたコードが動的に生成されたコードに置き換えられるためです。 ただし、 階層コンパイル を無効にするアプリケーションをプロファイリングしようとすると、シンボルが役立ちます。

複合 ReadyToRun

通常の ReadyToRun コンパイルでは、個別に処理および操作できるバイナリが生成されます。 .NET 6 以降、複合 ReadyToRun コンパイルのサポートが追加されました。 複合 ReadyToRun は、一緒に配布する必要があるアセンブリのセットをコンパイルします。 これには、コンパイラがより優れた最適化を実行でき、ReadyToRun プロセスを介してコンパイルできないメソッドのセットが減るという利点があります。 ただし、トレードオフとして、コンパイル速度が大幅に低下し、アプリケーションの全体的なファイル サイズが大幅に増加します。 これらのトレードオフにより、Composite ReadyToRun の使用は、 階層化コンパイル を無効にするアプリケーション、または 自己完結型 のデプロイで最適な起動時間を求めている Linux 上で実行されているアプリケーションにのみ推奨されます。 複合 ReadyToRun コンパイルを有効にするには、 <PublishReadyToRunComposite> プロパティを指定します。

<PropertyGroup>
  <PublishReadyToRunComposite>true</PublishReadyToRunComposite>
</PropertyGroup>

.NET 6 では、複合 ReadyToRun は 自己完結型 展開でのみサポートされています。

クロス プラットフォーム/アーキテクチャの制限

一部の SDK プラットフォームでは、ReadyToRun コンパイラは他のターゲット プラットフォームに対してクロスコンパイルが可能です。

.NET 6 以降のバージョンを対象とする場合、サポートされるコンパイル ターゲットについては、次の表で説明します。

SDK プラットフォーム サポート対象のターゲット プラットフォーム
Windows X64 Windows (X86、X64、Arm64)、Linux (X64、Arm32、Arm64)、macOS (X64、Arm64)
Windows X86 Windows (X86)、Linux (Arm32)
Linux X64 Linux (X64、Arm32、Arm64)、macOS (X64、Arm64)
Linux Arm32 Linux Arm32
Linux Arm64 Linux (X64、Arm32、Arm64)、macOS (X64、Arm64)
macOS X64 Linux (X64、Arm32、Arm64)、macOS (X64、Arm64)
macOS Arm64 Linux (X64、Arm32、Arm64)、macOS (X64、Arm64)

サポートされるコンパイル ターゲットは、.NET 5 以降を対象とする場合に、次の表で説明します。

SDK プラットフォーム サポート対象のターゲット プラットフォーム
Windows X64 Windows X86、Windows X64、Windows Arm64
Windows X86 Windows X86、Windows Arm32
Linux X64 Linux X86、Linux X64、Linux Arm32、Linux Arm64
Linux Arm32 Linux Arm32
Linux Arm64 Linux Arm64
macOS X64 macOS X64