共用方式為


ReadyToRun 編譯

您可以將應用程式元件編譯為 ReadyToRun (R2R) 格式,以改善 .NET 應用程式啟動時間和延遲。 R2R 是一種預先(AOT) 編譯。

R2R 二進位檔會透過減少 Just-In-Time (JIT) 編譯器在應用程式載入時所需執行的工作量,來改善啟動效能。 二進位檔包含的機器碼,與 JIT 所會產生的內容類似。 但是,R2R 二進位檔大小較大,因為它們會同時包含中繼語言 (IL) 程式碼 (在某些案例下仍需要使用),以及相同程式碼的原生版本。 只有在發佈以Linux x64或 Windows x64 等特定運行時間環境 (RID) 為目標的應用程式時,才能使用 R2R。

若要將專案編譯為 ReadyToRun,應用程式必須以設定為 true的 PublishReadyToRun 屬性發佈。

有兩種方式可將您的應用程式發佈為 ReadyToRun:

  1. 直接將 PublishReadyToRun 旗標指定至 dotnet publish 命令。 如需詳細資訊,請參閱 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 功能的影響

預先編譯會對應用程式效能產生複雜的效能影響,這可能會難以預測。 一般而言,元件的大小會成長為兩到三倍。 這會增加檔案的實體大小,可能會降低從磁碟載入元件的效能,並增加處理程式的工作集。 不過,作為回報,在執行期間編譯的方法數量通常會大幅減少。 結果是,具有大量程式代碼的應用程式會因為啟用 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 的運行。 這類原因可能包括,但不限於:

  • 使用個別元件中定義的泛型型別。
  • Interop 與原生碼。
  • 在目標機器上使用的硬體內建函數編譯器無法證明是安全的。
  • 某些不尋常的 IL 模式。
  • 透過反映或LINQ建立動態方法。

與分析器搭配使用的符號生成

使用 ReadyToRun 編譯應用程式時,分析工具可能需要符號來檢查產生的 ReadyToRun 檔案。 若要啟用符號產生,請指定 <PublishReadyToRunEmitSymbols> 屬性。

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

這些符號會放在發佈目錄中,而 Windows 的擴展名為 .ni.pdb,而 Linux 的擴展名為 .r2rmap。 這些檔案通常不會轉散發給終端客戶,而是通常會儲存在符號伺服器中。 一般而言,這些符號對於偵錯與啟動應用程式相關的效能問題很有用,因為 階層式編譯 會以動態產生的程式代碼取代 ReadyToRun 產生的程式代碼。 不過,如果嘗試分析停用 階層式編譯 的應用程式,符號將會很有用。

Composite ReadyToRun

一般 ReadyToRun 編譯會產生可個別維護及操作的二進位檔。 從 .NET 6 開始,已新增複合 ReadyToRun 編譯的支援。 複合ReadyToRun會編譯一組必須一起分發的程式集。 這的優點是編譯程式能夠執行更好的優化,並減少無法透過 ReadyToRun 程式編譯的方法集。 不過,由於取捨,編譯速度顯著降低,而應用程式的整體檔案大小則顯著增加。 由於這些取捨,建議只針對停用在Linux上執行的 階層式編譯 或使用 獨立 式部署尋求最佳啟動時間的應用程式,建議使用 Composite ReadyToRun。 若要啟用複合 ReadyToRun 編譯,請指定 <PublishReadyToRunComposite> 屬性。

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

備註

在 .NET 6 中,Composite 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