애플리케이션 어셈블리를 R2R(ReadyToRun) 형식으로 컴파일하여 .NET 애플리케이션 시작 시간 및 대기 시간을 개선할 수 있습니다. R2R은 AOT(Ahead-Of-Time) 컴파일 양식입니다.
R2R 이진 파일은 애플리케이션이 로드될 때 JIT(Just-In-Time) 컴파일러에서 수행해야 하는 작업량을 줄여 시작 성능을 향상합니다. 이진 파일에는 JIT에서 생성되는 코드와 비슷한 네이티브 코드가 포함되어 있습니다. 그러나 R2R 이진 파일은 일부 시나리오에서 필요한 IL(중간 언어) 코드와 동일한 코드의 네이티브 버전을 모두 포함하므로 크기가 더 큽니다. R2R은 Linux x64 또는 Windows x64와 같은 RID(특정 런타임 환경)를 대상으로 하는 앱을 게시하는 경우에만 사용할 수 있습니다.
프로젝트를 ReadyToRun으로 컴파일하려면 PublishReadyToRun 속성을 .로 설정 true
하여 애플리케이션을 게시해야 합니다.
앱을 ReadyToRun으로 게시하는 방법에는 두 가지가 있습니다.
dotnet publish 명령에 직접 PublishReadyToRun 플래그를 지정합니다. 자세한 내용은 dotnet publish 를 참조하세요.
dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true
프로젝트에서 속성을 지정합니다.
-
<PublishReadyToRun>
프로젝트에 설정을 추가합니다.
<PropertyGroup> <PublishReadyToRun>true</PublishReadyToRun> </PropertyGroup>
- 특수 매개 변수 없이 애플리케이션을 게시합니다.
dotnet publish -c Release -r win-x64
-
ReadyToRun 기능 사용의 영향
미리 컴파일은 예측하기 어려울 수 있는 애플리케이션 성능에 복잡한 성능 영향을 줍니다. 일반적으로 어셈블리의 크기는 2~3배 더 커지게 됩니다. 파일의 물리적 크기가 증가하면 디스크에서 어셈블리를 로드하는 성능이 저하되고 프로세스의 작업 집합이 증가할 수 있습니다. 그러나 그 대가로 런타임에 컴파일된 메서드의 수는 일반적으로 크게 줄어듭니다. 결과적으로 많은 양의 코드가 있는 대부분의 애플리케이션은 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가 실행되지 않을 것으로 예상되지 않습니다. 이러한 원인에는 다음이 포함될 수 있지만 이에 국한되지는 않습니다.
- 별도의 어셈블리에 정의된 제네릭 형식을 사용합니다.
- 네이티브 코드와 상호 운용합니다.
- 컴파일러에서 증명할 수 없는 하드웨어 내장 함수의 사용은 대상 컴퓨터에서 안전하게 사용할 수 있습니다.
- 특정 비정상적인 IL 패턴입니다.
- 리플렉션 또는 LINQ를 통해 동적 메서드를 생성합니다.
프로파일러와 함께 사용할 기호 생성
ReadyToRun을 사용하여 애플리케이션을 컴파일할 때 프로파일러에는 생성된 ReadyToRun 파일을 검사하기 위한 기호가 필요할 수 있습니다. 기호 생성을 사용하도록 설정하려면 속성을 지정합니다 <PublishReadyToRunEmitSymbols>
.
<PropertyGroup>
<PublishReadyToRunEmitSymbols>true</PublishReadyToRunEmitSymbols>
</PropertyGroup>
이러한 기호는 게시 디렉터리에 배치되고 Windows의 경우 .ni.pdb의 파일 확장명이 있으며 Linux의 경우 .r2rmap의 파일 확장명이 있습니다. 이러한 파일은 일반적으로 최종 고객에게 재배포되지 않고 일반적으로 기호 서버에 저장됩니다. 일반적으로 이러한 기호는 계층화된 컴파일 이 ReadyToRun 생성 코드를 동적으로 생성된 코드로 대체하므로 애플리케이션 시작과 관련된 성능 문제를 디버깅하는 데 유용합니다. 그러나 계층화된 컴파일 을 사용하지 않도록 설정하는 애플리케이션을 프로파일링하려고 하면 기호가 유용합니다.
Composite ReadyToRun
일반 ReadyToRun 컴파일은 개별적으로 서비스하고 조작할 수 있는 이진 파일을 생성합니다. .NET 6부터 복합 ReadyToRun 컴파일에 대한 지원이 추가되었습니다. Composite ReadyToRun은 함께 배포해야 하는 어셈블리 집합을 컴파일합니다. 이는 컴파일러가 더 나은 최적화를 수행할 수 있고 ReadyToRun 프로세스를 통해 컴파일할 수 없는 메서드 집합을 줄일 수 있다는 장점이 있습니다. 그러나 절충으로 컴파일 속도가 크게 감소하고 애플리케이션의 전체 파일 크기가 크게 증가합니다. 이러한 절충으로 인해 복합 ReadyToRun을 사용하는 것은 계층화된 컴파일 을 사용하지 않도록 설정하는 애플리케이션 또는 자체 포함 배포를 사용하여 최상의 시작 시간을 원하는 Linux에서 실행되는 애플리케이션에만 권장됩니다. 복합 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 | 리눅스 X86, 리눅스 X64, 리눅스 Arm32, 리눅스 Arm64 |
Linux Arm32 | Linux Arm32 |
Linux Arm64 | Linux Arm64 |
macOS X64 | macOS X64 |
.NET