Kompilacja ReadyToRun

Czas uruchamiania i opóźnienie aplikacji platformy .NET można poprawić, kompilując zestawy aplikacji jako format ReadyToRun (R2R). R2R to forma kompilacji Z wyprzedzeniem (AOT).

Pliki binarne R2R zwiększają wydajność uruchamiania, zmniejszając ilość pracy kompilatora just in time (JIT), który musi wykonać podczas ładowania aplikacji. Pliki binarne zawierają podobny kod macierzysty w porównaniu z elementem JIT, który byłby wygenerowany. Jednak pliki binarne R2R są większe, ponieważ zawierają zarówno kod języka pośredniego (IL), który jest nadal potrzebny w niektórych scenariuszach, oraz natywną wersję tego samego kodu. R2R jest dostępny tylko w przypadku publikowania aplikacji przeznaczonej dla określonych środowisk uruchomieniowych (RID), takich jak Linux x64 lub Windows x64.

Aby skompilować projekt jako ReadyToRun, aplikacja musi zostać opublikowana z właściwością PublishReadyToRun ustawioną na truewartość .

Istnieją dwa sposoby publikowania aplikacji jako ReadyToRun:

  1. Określ flagę PublishReadyToRun bezpośrednio do polecenia dotnet publish. Aby uzyskać szczegółowe informacje, zobacz dotnet publish (publikowanie dotnet ).

    dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true
    
  2. Określ właściwość w projekcie.

    • <PublishReadyToRun> Dodaj ustawienie do projektu.
    <PropertyGroup>
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    
    • Opublikuj aplikację bez żadnych specjalnych parametrów.
    dotnet publish -c Release -r win-x64
    

Wpływ korzystania z funkcji ReadyToRun

Kompilacja z wyprzedzeniem ma złożony wpływ na wydajność aplikacji, co może być trudne do przewidzenia. Ogólnie rzecz biorąc, rozmiar zestawu wzrośnie do przedziału od dwóch do trzech razy większych. Ten wzrost rozmiaru fizycznego pliku może zmniejszyć wydajność ładowania zestawu z dysku i zwiększyć zestaw roboczy procesu. Jednak w zamian liczba metod skompilowanych w czasie wykonywania jest zwykle znacznie mniejsza. W rezultacie większość aplikacji, które mają duże ilości kodu, otrzymuje duże korzyści z wydajności dzięki włączeniu funkcji ReadyToRun. Aplikacje, które mają niewielkie ilości kodu, prawdopodobnie nie poprawią możliwości włączenia funkcji ReadyToRun, ponieważ biblioteki środowiska uruchomieniowego platformy .NET zostały już wstępnie skompilowane z funkcją ReadyToRun.

Omówione tutaj ulepszenia uruchamiania dotyczą nie tylko uruchamiania aplikacji, ale także pierwszego użycia dowolnego kodu w aplikacji. Na przykład funkcja ReadyToRun może służyć do zmniejszenia opóźnienia odpowiedzi pierwszego użycia internetowego interfejsu API w aplikacji ASP.NET.

Interakcja z kompilacją warstwową

Wygenerowany kod z wyprzedzeniem nie jest tak wysoce zoptymalizowany, jak kod generowany przez JIT. Aby rozwiązać ten problem, kompilacja warstwowa zastąpi powszechnie używane metody ReadyToRun metodami wygenerowanymi przez tryb JIT.

Jak wybrano zestaw wstępnie skompilowanych zestawów?

Zestaw SDK będzie wstępnie kompilować zestawy dystrybuowane z aplikacją. W przypadku aplikacji samodzielnie ten zestaw zestawów będzie zawierać strukturę. Pliki binarne języka C++/CLI nie kwalifikują się do kompilacji ReadyToRun.

Aby wykluczyć określone zestawy z przetwarzania ReadyToRun, użyj <PublishReadyToRunExclude> listy.

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

Jaki jest zestaw metod do wstępnego kompilowania?

Kompilator spróbuje wstępnie skompilować dowolną liczbę metod. Jednak z różnych powodów nie oczekuje się, że użycie funkcji ReadyToRun uniemożliwi wykonywanie trybu JIT. Takie przyczyny mogą obejmować, ale nie są ograniczone do:

  • Użycie typów ogólnych zdefiniowanych w oddzielnych zestawach.
  • Współdziałanie z kodem natywnym.
  • Korzystanie z funkcji wewnętrznych sprzętu, których kompilator nie może udowodnić, jest bezpieczne do użycia na maszynie docelowej.
  • Niektóre niezwykłe wzorce IL.
  • Dynamiczne tworzenie metody za pośrednictwem odbicia lub LINQ.

Generowanie symboli do użycia z profilerami

Podczas kompilowania aplikacji przy użyciu funkcji ReadyToRun profileers mogą wymagać symboli do zbadania wygenerowanych plików ReadyToRun. Aby włączyć generowanie symboli <PublishReadyToRunEmitSymbols> , określ właściwość .

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

Te symbole zostaną umieszczone w katalogu publikowania, a dla systemu Windows będzie mieć rozszerzenie pliku .ni.pdb, a dla systemu Linux będzie mieć rozszerzenie pliku r2rmap. Te pliki nie są zwykle redystrybuowane do klientów końcowych, ale zazwyczaj są przechowywane na serwerze symboli. Ogólnie rzecz biorąc, te symbole są przydatne do debugowania problemów z wydajnością związanych z uruchamianiem aplikacji, ponieważ kompilacja warstwowa zastąpi wygenerowany kod ReadyToRun dynamicznie wygenerowanym kodem. Jeśli jednak próbujesz profilować aplikację, która wyłącza kompilację warstwową , symbole będą przydatne.

Gotowe do uruchomienia złożonego

Kompilacja Normal ReadyToRun tworzy pliki binarne, które można obsługiwać i manipulować pojedynczo. Począwszy od platformy .NET 6, dodano obsługę kompilacji Composite ReadyToRun. Composite ReadyToRun kompiluje zestaw zestawów, które muszą być dystrybuowane razem. Ma to zaletę, że kompilator jest w stanie wykonywać lepsze optymalizacje i zmniejsza zestaw metod, których nie można skompilować za pośrednictwem procesu ReadyToRun. Jednak w miarę kompromisu szybkość kompilacji jest znacznie zmniejszona, a ogólny rozmiar pliku aplikacji jest znacznie zwiększany. Ze względu na te kompromisy użycie funkcji Composite ReadyToRun jest zalecane tylko w przypadku aplikacji, które wyłączają kompilację warstwową lub aplikacje działające w systemie Linux, które szukają najlepszego czasu uruchamiania w przypadku samodzielnego wdrożenia. Aby włączyć złożoną kompilację <PublishReadyToRunComposite> ReadyToRun, określ właściwość .

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

Uwaga

Na platformie .NET 6 funkcja Composite ReadyToRun jest obsługiwana tylko w przypadku wdrożenia samodzielnego .

Ograniczenia międzyplatformowe/architektury

W przypadku niektórych platform zestawu SDK kompilator ReadyToRun może kompilować krzyżowo dla innych platform docelowych.

Obsługiwane elementy docelowe kompilacji opisano w poniższej tabeli podczas określania wartości docelowej dla platformy .NET 6 i nowszych wersji.

Platforma SDK Obsługiwane platformy docelowe
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)

Obsługiwane elementy docelowe kompilacji opisano w poniższej tabeli podczas określania wartości docelowej dla platformy .NET 5 i poniżej.

Platforma SDK Obsługiwane platformy docelowe
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