ReadyToRun-compilatie

Opstarttijd en latentie van .NET-toepassingen kunnen worden verbeterd door uw toepassingsassembly's te compileren als ReadyToRun-indeling (R2R). R2R is een vorm van AOT-compilatie (ahead-of-time).

Binaire R2R-bestanden verbeteren de opstartprestaties door de hoeveelheid werk te verminderen die de Just-In-Time-compiler (JIT) moet doen wanneer uw toepassing wordt geladen. De binaire bestanden bevatten vergelijkbare systeemeigen code vergeleken met wat de JIT zou produceren. Binaire R2R-bestanden zijn echter groter omdat ze zowel tussenliggende taalcode (IL) bevatten, die nog steeds nodig is voor sommige scenario's en de systeemeigen versie van dezelfde code. R2R is alleen beschikbaar wanneer u een app publiceert die gericht is op specifieke runtime-omgevingen (RID), zoals Linux x64 of Windows x64.

Als u uw project wilt compileren als ReadyToRun, moet de toepassing worden gepubliceerd met de eigenschap PublishReadyToRun ingesteld op true.

U kunt uw app op twee manieren publiceren als ReadyToRun:

  1. Geef de vlag PublishReadyToRun rechtstreeks op naar de opdracht dotnet publish. Zie dotnet publish for details.

    dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true
    
  2. Geef de eigenschap in het project op.

    • Voeg de <PublishReadyToRun> instelling toe aan uw project.
    <PropertyGroup>
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    
    • Publiceer de toepassing zonder speciale parameters.
    dotnet publish -c Release -r win-x64
    

Impact van het gebruik van de functie ReadyToRun

Compilatie van tevoren heeft complexe invloed op de prestaties van toepassingen, wat moeilijk te voorspellen kan zijn. Over het algemeen zal de grootte van een assembly tussen twee tot drie keer groter worden. Deze toename van de fysieke grootte van het bestand kan de prestaties van het laden van de assembly van de schijf verminderen en de werkset van het proces verhogen. Als resultaat wordt echter het aantal methoden dat tijdens de runtime is gecompileerd, doorgaans aanzienlijk verminderd. Het resultaat is dat de meeste toepassingen met grote hoeveelheden code profiteren van het inschakelen van ReadyToRun. Toepassingen met kleine hoeveelheden code ervaren waarschijnlijk geen aanzienlijke verbetering van het inschakelen van ReadyToRun, omdat de .NET-runtimebibliotheken al vooraf zijn gecompileerd met ReadyToRun.

De hier besproken opstartverbetering is niet alleen van toepassing op het opstarten van toepassingen, maar ook op het eerste gebruik van code in de toepassing. ReadyToRun kan bijvoorbeeld worden gebruikt om de reactielatentie van het eerste gebruik van web-API in een ASP.NET toepassing te verminderen.

Interactie met gelaagde compilatie

Gegenereerde code van tevoren is niet zo sterk geoptimaliseerd als code die door de JIT wordt geproduceerd. Om dit probleem op te lossen, vervangt gelaagde compilatie veelgebruikte ReadyToRun-methoden door door JIT gegenereerde methoden.

Hoe wordt de set vooraf gecompileerde assembly's gekozen?

Met de SDK worden de assembly's vooraf gecompileerde die met de toepassing worden gedistribueerd. Voor zelfstandige toepassingen bevat deze set assembly's het framework. Binaire C++/CLI-bestanden komen niet in aanmerking voor ReadyToRun-compilatie.

Als u specifieke assembly's wilt uitsluiten van ReadyToRun-verwerking, gebruikt u de <PublishReadyToRunExclude> lijst.

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

Hoe wordt de set methoden gekozen om vooraf te compileren?

De compiler probeert zoveel mogelijk methoden vooraf te compileren. Om verschillende redenen wordt echter niet verwacht dat het uitvoeren van de JIT met behulp van de functie ReadyToRun wordt voorkomen. Dergelijke redenen kunnen omvatten, maar zijn niet beperkt tot:

  • Gebruik van algemene typen die zijn gedefinieerd in afzonderlijke assembly's.
  • Interoperabiliteit met systeemeigen code.
  • Het gebruik van hardware-intrinsieken die de compiler niet kan bewijzen, is veilig te gebruiken op een doelcomputer.
  • Bepaalde ongebruikelijke IL-patronen.
  • Dynamische methode maken via reflectie of LINQ.

Symboolgeneratie voor gebruik met profilers

Bij het compileren van een toepassing met ReadyToRun zijn voor profilers mogelijk symbolen vereist voor het controleren van de gegenereerde ReadyToRun-bestanden. Als u het genereren van symbolen wilt inschakelen, geeft u de <PublishReadyToRunEmitSymbols> eigenschap op.

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

Deze symbolen worden in de publicatiemap geplaatst en voor Windows heeft de bestandsextensie .ni.pdb en voor Linux bestandsextensie .r2rmap. Deze bestanden worden doorgaans niet opnieuw gedistribueerd naar eindklanten, maar worden meestal opgeslagen op een symboolserver. Over het algemeen zijn deze symbolen handig voor het opsporen van prestatieproblemen met betrekking tot het opstarten van toepassingen, omdat Gelaagde compilatie de door ReadyToRun gegenereerde code vervangt door dynamisch gegenereerde code. Als u echter probeert een toepassing te profilen die gelaagde compilatie uitschakelt, zijn de symbolen nuttig.

Samengestelde ReadyToRun

Normal ReadyToRun compilatie produceert binaire bestanden die afzonderlijk kunnen worden onderhouden en bewerkt. Vanaf .NET 6 is ondersteuning voor samengestelde ReadyToRun-compilatie toegevoegd. Samengestelde ReadyToRun compileert een set assembly's die samen moeten worden gedistribueerd. Dit heeft het voordeel dat de compiler betere optimalisaties kan uitvoeren en de set methoden vermindert die niet kunnen worden gecompileerd via het ReadyToRun-proces. Als compromis wordt de compilatiesnelheid echter aanzienlijk verlaagd en wordt de totale bestandsgrootte van de toepassing aanzienlijk verhoogd. Vanwege deze afwegingen wordt het gebruik van Samengestelde ReadyToRun alleen aanbevolen voor toepassingen die gelaagde compilatie uitschakelen of toepassingen die worden uitgevoerd op Linux die op zoek zijn naar de beste opstarttijd met zelfstandige implementatie. Als u samengestelde ReadyToRun-compilatie wilt inschakelen, geeft u de <PublishReadyToRunComposite> eigenschap op.

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

Notitie

In .NET 6 wordt Samengestelde ReadyToRun alleen ondersteund voor zelfstandige implementatie.

Beperkingen voor platformoverschrijdende/architectuur

Voor sommige SDK-platforms is de ReadyToRun-compiler geschikt voor cross-compileren voor andere doelplatforms.

Ondersteunde compilatiedoelen worden beschreven in de onderstaande tabel wanneer u zich richt op .NET 6 en latere versies.

SDK-platform Ondersteunde doelplatforms
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)

Ondersteunde compilatiedoelen worden beschreven in de onderstaande tabel wanneer u zich richt op .NET 5 en lager.

SDK-platform Ondersteunde doelplatforms
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