ReadyToRun-kompilering

Starttid och svarstid för .NET-program kan förbättras genom kompilering av programsammansättningar som R2R-format (ReadyToRun). R2R är en form av AOT-kompilering (ahead-of-time).

R2R-binärfiler förbättrar startprestanda genom att minska mängden arbete som jit-kompilatorn (just-in-time) behöver utföra när programmet läses in. Binärfilerna innehåller liknande intern kod jämfört med vad JIT skulle generera. R2R-binärfiler är dock större eftersom de innehåller både mellanliggande språkkod (IL), som fortfarande behövs för vissa scenarier och den interna versionen av samma kod. R2R är endast tillgängligt när du publicerar en app som riktar sig till specifika körningsmiljöer (RID) som Linux x64 eller Windows x64.

Om du vill kompilera projektet som ReadyToRun måste programmet publiceras med egenskapen PublishReadyToRun inställd på true.

Det finns två sätt att publicera din app som ReadyToRun:

  1. Ange flaggan PublishReadyToRun direkt till dotnet-publiceringskommandot. Mer information finns i dotnet publish .

    dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true
    
  2. Ange egenskapen i projektet.

    • Lägg till inställningen i <PublishReadyToRun> projektet.
    <PropertyGroup>
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    
    • Publicera programmet utan några särskilda parametrar.
    dotnet publish -c Release -r win-x64
    

Effekten av att använda funktionen ReadyToRun

Kompilering i förväg har komplex prestandapåverkan på programmets prestanda, vilket kan vara svårt att förutsäga. I allmänhet växer storleken på en sammansättning till mellan två och tre gånger större. Den här ökningen av filens fysiska storlek kan minska prestandan vid inläsning av sammansättningen från disken och öka arbetsuppsättningen för processen. I gengäld minskas dock antalet metoder som kompileras vid körningen vanligtvis avsevärt. Resultatet är att de flesta program som har stora mängder kod får stora prestandafördelar med att aktivera ReadyToRun. Program som har små mängder kod kommer sannolikt inte att uppleva någon betydande förbättring jämfört med att aktivera ReadyToRun, eftersom .NET-körningsbiblioteken redan har förkompilerats med ReadyToRun.

Startförbättringen som beskrivs här gäller inte bara för programstart, utan även för den första användningen av någon kod i programmet. Till exempel kan ReadyToRun användas för att minska svarsfördröjningen för den första användningen av webb-API i ett ASP.NET program.

Interaktion med nivåindelad kompilering

Genererad kod i förväg är inte lika mycket optimerad som kod som skapas av JIT. För att lösa det här problemet ersätter nivåindelad kompilering vanliga ReadyToRun-metoder med JIT-genererade metoder.

Hur väljs uppsättningen förkompilerade sammansättningar?

SDK:t förkompilerar de sammansättningar som distribueras med programmet. För fristående program innehåller den här uppsättningen sammansättningar ramverket. C++/CLI-binärfiler är inte berättigade till ReadyToRun-kompilering.

Om du vill exkludera specifika sammansättningar från ReadyToRun-bearbetning använder du listan <PublishReadyToRunExclude> .

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

Hur väljs den uppsättning metoder som ska förkompileras?

Kompilatorn försöker förkompilera så många metoder som möjligt. Av olika anledningar är det dock inte förväntat att jit-funktionen från att köras med funktionen ReadyToRun. Sådana skäl kan vara, men är inte begränsade till:

  • Användning av generiska typer som definierats i separata sammansättningar.
  • Interop med inbyggd kod.
  • Användning av maskinvara som kompilatorn inte kan bevisa är säker att använda på en måldator.
  • Vissa ovanliga IL-mönster.
  • Dynamisk metodskapande via reflektion eller LINQ.

Symbolgenerering för användning med profilerare

När du kompilerar ett program med ReadyToRun kan profilerare kräva symboler för att undersöka de genererade ReadyToRun-filerna. Om du vill aktivera symbolgenerering anger du egenskapen <PublishReadyToRunEmitSymbols> .

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

Dessa symboler placeras i publiceringskatalogen och för Windows har filnamnstillägget .ni.pdb och för Linux har filnamnstillägget .r2rmap. Dessa filer distribueras vanligtvis inte om till slutkunder, utan lagras vanligtvis på en symbolserver. I allmänhet är dessa symboler användbara för felsökning av prestandaproblem som rör start av program, eftersom nivåindelad kompilering ersätter den ReadyToRun-genererade koden med dynamiskt genererad kod. Men om du försöker profilera ett program som inaktiverar nivåindelad kompilering är symbolerna användbara.

Sammansatt ReadyToRun

Normal ReadyToRun-kompilering genererar binärfiler som kan hanteras och manipuleras individuellt. Från och med .NET 6 har stöd för sammansatt ReadyToRun-kompilering lagts till. Sammansatt ReadyToRun kompilerar en uppsättning sammansättningar som måste distribueras tillsammans. Detta har fördelen att kompilatorn kan utföra bättre optimeringar och minskar den uppsättning metoder som inte kan kompileras via ReadyToRun-processen. Som en kompromiss minskar dock kompileringshastigheten avsevärt och programmets totala filstorlek ökar avsevärt. På grund av dessa kompromisser rekommenderas användning av Sammansatt ReadyToRun endast för program som inaktiverar nivåindelad kompilering eller program som körs på Linux och som söker den bästa starttiden med fristående distribution. Om du vill aktivera sammansatt ReadyToRun-kompilering anger du egenskapen <PublishReadyToRunComposite> .

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

Kommentar

I .NET 6 stöds sammansatt ReadyToRun endast för fristående distribution.

Begränsningar för plattformsoberoende/arkitektur

För vissa SDK-plattformar kan ReadyToRun-kompilatorn korskompilera för andra målplattformar.

Kompileringsmål som stöds beskrivs i tabellen nedan när du riktar in dig på .NET 6 och senare versioner.

SDK-plattform Målplattformar som stöds
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)

Kompileringsmål som stöds beskrivs i tabellen nedan när du riktar in dig på .NET 5 och nedan.

SDK-plattform Målplattformar som stöds
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