Compilazione ReadyToRun

L'ora di avvio e la latenza dell'applicazione .NET possono essere migliorate compilando gli assembly dell'applicazione come formato ReadyToRun (R2R). R2R è un formato di compilazione AOT (Ahead-of-time).

I file binari R2R migliorano le prestazioni di avvio riducendo la quantità di lavoro che deve eseguire il compilatore JIT (Just-in-time) durante il caricamento dell'applicazione. I file binari contengono codice nativo simile a ciò che viene generato dal compilatore JIT. I file binari R2R, tuttavia, sono più grandi poiché contengono sia il codice in linguaggio intermedio, che è comunque necessario per alcuni scenari, sia la versione nativa dello stesso codice. R2R è disponibile solo quando si pubblica un'app destinata a specifici ambienti di runtime (RID) come Linux x64 o Windows x64.

Per compilare il progetto come ReadyToRun, l'applicazione deve essere pubblicata con la proprietà PublishReadyToRun impostata su true.

Esistono due modi per pubblicare l'app come ReadyToRun:

  1. Specificare il flag PublishReadyToRun direttamente al comando dotnet publish. Per informazioni dettagliate, vedere dotnet publish (Pubblica dotnet ).

    dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true
    
  2. Specificare la proprietà nel progetto.

    • Aggiungere l'impostazione <PublishReadyToRun> al progetto.
    <PropertyGroup>
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    
    • Pubblicare l'applicazione senza parametri speciali.
    dotnet publish -c Release -r win-x64
    

Impatto sull'uso della funzionalità ReadyToRun

La compilazione in anticipo ha un impatto sulle prestazioni complesse sulle prestazioni dell'applicazione, che possono essere difficili da prevedere. In generale, le dimensioni di un assembly cresceranno tra due e tre volte più grandi. Questo aumento delle dimensioni fisiche del file può ridurre le prestazioni del caricamento dell'assembly dal disco e aumentare il set di lavoro del processo. Tuttavia, in restituzione il numero di metodi compilati in fase di esecuzione è in genere ridotto notevolmente. Il risultato è che la maggior parte delle applicazioni che hanno grandi quantità di codice ricevono grandi vantaggi dalle prestazioni dall'abilitazione di ReadyToRun. Le applicazioni con piccole quantità di codice probabilmente non avranno un miglioramento significativo dall'abilitazione di ReadyToRun, poiché le librerie di runtime .NET sono già state precompilate con ReadyToRun.

Il miglioramento di avvio illustrato qui si applica non solo all'avvio dell'applicazione, ma anche al primo uso di qualsiasi codice nell'applicazione. Ad esempio, ReadyToRun può essere usato per ridurre la latenza di risposta del primo uso dell'API Web in un'applicazione ASP.NET.

Interazione con la compilazione a livelli

Il codice generato in anticipo non è altamente ottimizzato come codice prodotto dal JIT. Per risolvere questo problema, la compilazione a livelli sostituirà i metodi ReadyToRun comunemente usati con metodi generati da JIT.

Come viene scelto il set di assembly precompilati?

L'SDK precompila gli assembly distribuiti con l'applicazione. Per le applicazioni autonome, questo set di assembly includerà il framework. I file binari C++/CLI non sono idonei per la compilazione ReadyToRun.

Per escludere assembly specifici dall'elaborazione ReadyToRun, usare l'elenco <PublishReadyToRunExclude> .

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

Come viene scelto il set di metodi da precompilare?

Il compilatore tenterà di precompilare il numero possibile di metodi. Tuttavia, per vari motivi, non è previsto che l'uso della funzionalità ReadyToRun impedirà l'esecuzione del JIT. Tali motivi possono includere, ma non sono limitati a:

  • Uso di tipi generici definiti in assembly separati.
  • Interoperabilità con codice nativo.
  • L'uso di intrinseci hardware che il compilatore non può dimostrare è sicuro da usare in un computer di destinazione.
  • Alcuni modelli di IL insoliti.
  • Creazione dinamica del metodo tramite reflection o LINQ.

Generazione dei simboli da usare con i profiler

Quando si compila un'applicazione con ReadyToRun, i profiler possono richiedere simboli per esaminare i file ReadyToRun generati. Per abilitare la generazione dei simboli, specificare la <PublishReadyToRunEmitSymbols> proprietà .

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

Questi simboli verranno posizionati nella directory di pubblicazione e per Windows avranno un'estensione di file di .ni.pdb e per Linux avrà un'estensione file di .r2rmap. Questi file non vengono in genere ridistribuito ai clienti finali, ma in genere verranno archiviati in un server simboli. In generale questi simboli sono utili per il debug dei problemi di prestazioni correlati all'avvio delle applicazioni, poiché la compilazione a livelli sostituirà il codice ReadyToRun generato con codice generato dinamicamente. Tuttavia, se si tenta di profilare un'applicazione che disabilita la compilazione a livelli , i simboli saranno utili.

Composite ReadyToRun

La compilazione Normal ReadyToRun produce file binari che possono essere gestiti e modificati singolarmente. A partire da .NET 6, è stato aggiunto il supporto per la compilazione Composite ReadyToRun. Composite ReadyToRun compila un set di assembly che devono essere distribuiti insieme. Questo offre il vantaggio che il compilatore è in grado di eseguire ottimizzazioni migliori e riduce il set di metodi che non possono essere compilati tramite il processo ReadyToRun. Tuttavia, come compromesso, la velocità di compilazione è notevolmente diminuita e la dimensione complessiva del file dell'applicazione è notevolmente aumentata. A causa di questi compromessi, l'uso di Composite ReadyToRun è consigliato solo per le applicazioni che disabilitano compilazione a livelli o applicazioni in esecuzione in Linux che cercano il tempo di avvio migliore con la distribuzione autonoma . Per abilitare la compilazione ReadyToRun composita, specificare la <PublishReadyToRunComposite> proprietà .

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

Nota

In .NET 6, Composite ReadyToRun è supportato solo per la distribuzione autonoma .

Limitazioni per ambienti con più piattaforme o architetture

Per alcune piattaforme SDK, il compilatore ReadyToRun è in grado di eseguire la compilazione incrociata per altre piattaforme di destinazione.

Le destinazioni di compilazione supportate sono descritte nella tabella seguente quando si punta a .NET 6 e versioni successive.

SDK platform Piattaforme di destinazione supportate
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)

Le destinazioni di compilazione supportate sono descritte nella tabella seguente quando si punta a .NET 5 e versioni successive.

SDK platform Piattaforme di destinazione supportate
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