BenchmarkDotnet은 메소드를 벤치 마크로 변환하고 성능을 추적하며 재현 가능한 측정 실험을 공유하는 데 도움이됩니다. 단위 테스트를 작성하는 것보다 어렵지 않습니다! 후드 아래에서는 Perfolizer 통계 엔진 덕분에 신뢰할 수 있고 정확한 결과를 보장하는 많은 마법을 수행합니다. BenchmarkDotnet은 인기있는 벤치마킹 실수로부터 귀하를 보호하고 벤치 마크 설계에 문제가 있거나 측정 된 측정에 문제가 있는지 경고합니다. 결과는 실험에 대한 모든 중요한 사실을 강조하는 사용자 친화적 인 형태로 표시됩니다. BenchmarkDotnet은 .NET Runtime, .NET Compiler, .NET Performance 등을 포함한 22000 개 이상의 GitHub 프로젝트에서 이미 채택되었습니다.
벤치 마크를 쓰기 쉽습니다. 다음 예제를 확인하십시오 (복사 가능한 버전은 여기에 있습니다).
[ SimpleJob ( RuntimeMoniker . Net472 , baseline : true ) ]
[ SimpleJob ( RuntimeMoniker . NetCoreApp30 ) ]
[ SimpleJob ( RuntimeMoniker . NativeAot70 ) ]
[ SimpleJob ( RuntimeMoniker . Mono ) ]
[ RPlotExporter ]
public class Md5VsSha256
{
private SHA256 sha256 = SHA256 . Create ( ) ;
private MD5 md5 = MD5 . Create ( ) ;
private byte [ ] data ;
[ Params ( 1000 , 10000 ) ]
public int N ;
[ GlobalSetup ]
public void Setup ( )
{
data = new byte [ N ] ;
new Random ( 42 ) . NextBytes ( data ) ;
}
[ Benchmark ]
public byte [ ] Sha256 ( ) => sha256 . ComputeHash ( data ) ;
[ Benchmark ]
public byte [ ] Md5 ( ) => md5 . ComputeHash ( data ) ;
}BenchmarkDotnet은 모든 런타임에서 벤치 마크를 자동으로 실행하고 측정을 집계하며 가장 중요한 정보와 함께 요약 테이블을 인쇄합니다.
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.17763.805 (1809/October2018Update/Redstone5)
Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
[ Host ] : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
Net472 : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
NetCoreApp30 : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT
NativeAot70 : .NET 7.0.0-preview.4.22172.7, X64 NativeAOT
Mono : Mono 6.4.0 (Visual Studio), X64
| Method | Runtime | N | Mean | Error | StdDev | Ratio |
| ------- | -------------- | ------ | -----------: | ----------: | ----------: | ------: |
| Sha256 | .NET 4.7.2 | 1000 | 7.735 us | 0.1913 us | 0.4034 us | 1.00 |
| Sha256 | .NET Core 3.0 | 1000 | 3.989 us | 0.0796 us | 0.0745 us | 0.50 |
| Sha256 | NativeAOT 7.0 | 1000 | 4.091 us | 0.0811 us | 0.1562 us | 0.53 |
| Sha256 | Mono | 1000 | 13.117 us | 0.2485 us | 0.5019 us | 1.70 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 1000 | 2.872 us | 0.0552 us | 0.0737 us | 1.00 |
| Md5 | .NET Core 3.0 | 1000 | 1.848 us | 0.0348 us | 0.0326 us | 0.64 |
| Md5 | NativeAOT 7.0 | 1000 | 1.817 us | 0.0359 us | 0.0427 us | 0.63 |
| Md5 | Mono | 1000 | 3.574 us | 0.0678 us | 0.0753 us | 1.24 |
| | | | | | | |
| Sha256 | .NET 4.7.2 | 10000 | 74.509 us | 1.5787 us | 4.6052 us | 1.00 |
| Sha256 | .NET Core 3.0 | 10000 | 36.049 us | 0.7151 us | 1.0025 us | 0.49 |
| Sha256 | NativeAOT 7.0 | 10000 | 36.253 us | 0.7076 us | 0.7571 us | 0.49 |
| Sha256 | Mono | 10000 | 116.350 us | 2.2555 us | 3.0110 us | 1.58 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 10000 | 17.308 us | 0.3361 us | 0.4250 us | 1.00 |
| Md5 | .NET Core 3.0 | 10000 | 15.726 us | 0.2064 us | 0.1930 us | 0.90 |
| Md5 | NativeAOT 7.0 | 10000 | 15.627 us | 0.2631 us | 0.2461 us | 0.89 |
| Md5 | Mono | 10000 | 30.205 us | 0.5868 us | 0.6522 us | 1.74 |
측정 된 데이터는 플롯을 포함하여 다른 형식 (MD, HTML, CSV, XML, JSON 등)으로 내보낼 수 있습니다.
지원되는 런타임 : .NET 5+, .NET 프레임 워크 4.6.1+, .NET Core 3.1+, Mono, NativeAot
지원되는 언어 : C#, F#, Visual Basic
지원되는 OS : Windows, Linux, MacOS
지원되는 아키텍처 : X86, X64, ARM, ARM64, WASM 및 LOONGARCH64
BenchmarkDotnet에는 포괄적 인 성능 조사에 필수적인 수많은 기능이 있습니다. 네 가지 측면은 이러한 기능의 디자인을 단순성 , 자동화 , 신뢰성 및 친근감을 정의합니다.
벤치 마크를 쓰려면 숙련 된 성능 엔지니어가 될 필요는 없습니다. 간단한 API를 사용하여 선언적 스타일로 매우 복잡한 성능 실험을 설계 할 수 있습니다.
예를 들어, 벤치 마크를 매개 변수화하려면 [Params(1, 2, 3)] 으로 필드 또는 속성을 표시하십시오. 벤치 마크 도트는 각 경우에 대한 지정된 모든 값을 열거하고 실행 벤치 마크를 실행합니다. 벤치 마크를 서로 비교하려면 [Benchmark(Baseline = true)] 통해 벤치 마크 중 하나를 기준으로 표시합니다. 벤치 마크 도트는이를 다른 모든 벤치 마크와 비교합니다. 다른 환경에서 성능을 비교하려면 작업을 사용하십시오. 예를 들어 .NET Core 3.1 및 [SimpleJob(RuntimeMoniker.NetCoreApp31)] 및 [SimpleJob(RuntimeMoniker.Mono)] 를 통해 모든 벤치 마크를 실행할 수 있습니다.
속성이 마음에 들지 않으면 유창한 스타일을 통해 대부분의 API를 호출하고 다음과 같은 코드를 쓸 수 있습니다.
ManualConfig . CreateEmpty ( ) // A configuration for our benchmarks
. AddJob ( Job . Default // Adding first job
. WithRuntime ( ClrRuntime . Net472 ) // .NET Framework 4.7.2
. WithPlatform ( Platform . X64 ) // Run as x64 application
. WithJit ( Jit . LegacyJit ) // Use LegacyJIT instead of the default RyuJIT
. WithGcServer ( true ) // Use Server GC
) . AddJob ( Job . Default // Adding second job
. AsBaseline ( ) // It will be marked as baseline
. WithEnvironmentVariable ( "Key" , "Value" ) // Setting an environment variable
. WithWarmupCount ( 0 ) // Disable warm-up stage
) ;명령 줄 경험을 선호하는 경우 모든 콘솔 응용 프로그램에서 콘솔 인수를 통해 벤치 마크를 구성 할 수 있습니다 (다른 유형의 응용 프로그램은 지원되지 않음).
신뢰할 수있는 벤치 마크에는 항상 많은 보일러 플레이트 코드가 포함됩니다.
전형적인 경우에 무엇을 해야하는지 생각해 봅시다. 먼저 파일럿 실험을 수행하고 최상의 수의 메소드 호출을 결정해야합니다. 다음으로 여러 워밍업 반복을 실행하고 벤치 마크가 정상 상태를 달성해야합니다. 그런 다음 주요 반복을 실행하고 기본 통계를 계산해야합니다. 벤치 마크에서 일부 값을 계산하면 어떻게 든 데드 코드 제거를 방지해야합니다. 루프를 사용하는 경우 결과에 대한 루프 Unforling의 영향 (프로세서 아키텍처에 따라 다름)에주의해야합니다. 결과를 얻으면 다중 분류 또는 매우 높은 특이 치와 같은 획득 된 성능 분포의 특수 특성을 확인해야합니다. 또한 인프라의 오버 헤드를 평가하고 결과에서 공제해야합니다. 여러 환경을 테스트하려면 각 환경에서 측정을 수행하고 결과를 수동으로 집계해야합니다.
이 코드를 처음부터 작성하면 실수를 쉽게하고 측정을 망치는 것이 쉽습니다. 벤치마킹 중에 따라야하는 전체 체크리스트의 단축 버전입니다. 적절하게 처리 해야하는 추가적인 숨겨진 함정이 많이 있습니다. 다행히도 BenchmarkDotnet 이이 지루하고 시간이 많이 걸리는 것들을 수행하기 때문에 걱정하지 않아야합니다.
또한 도서관은 조사 중에 수행 할 고급 작업을 도와 줄 수 있습니다. 예를 들어, BenchmarkDotnet은 벤치 마크에 대한 관리 및 기본 메모리 트래픽을 측정하고 인쇄 분해 목록을 측정 할 수 있습니다.
손으로 쓴 많은 벤치 마크는 잘못된 숫자를 생성하여 잘못된 비즈니스 결정으로 이어집니다. BenchmarkDotnet은 대부분의 벤치마킹 함정으로부터 귀하를 보호하고 높은 측정 정밀도를 달성 할 수 있습니다.
완벽한 메소드 호출 수, 워밍업 수 및 실제 반복에 대해 걱정하지 않아야합니다. BenchmarkDotnet은 최상의 벤치마킹 매개 변수를 선택하고 측정 프리비전과 모든 벤치 마크 실행의 총 지속 시간 간의 우수한 트레이드 오프를 달성하려고합니다. 따라서 "100 회 반복을 수행 해야하는 마법 숫자"를 사용해서는 안됩니다. 도서관은 통계 메트릭의 값에 따라 귀하를 위해 수행합니다.
BenchmarkDotnet은 또한 해당 결과가 신뢰할 수 없기 때문에 디버그 모드를 사용하여 구축 된 최적화되지 않은 어셈블리의 벤치마킹을 방지합니다. 디버거가 부착되어 있거나 하이퍼 바이저 (Hyperv, VMware, VirtualBox)를 사용하거나 현재 환경에 다른 문제가있는 경우 라이브러리가 경고를 인쇄합니다.
6 년 이상의 개발 동안, 우리는 측정을 망칠 수있는 수십 가지의 다양한 문제에 직면했습니다. BenchmarkDotnet에는 결과의 신뢰성을 높이는 데 도움이되는 많은 휴리스틱, 수표, 해킹 및 트릭이 많이 있습니다.
성능 데이터 분석은주의, 지식 및 경험이 필요한 시간이 많이 걸리는 활동입니다. BenchmarkDotnet 은이 분석의 주요 부분을 수행하고 결과를 사용자 친화적 인 양식으로 표시합니다.
실험 후에는 실행 된 벤치 마크에 대한 유용한 데이터가 많이 포함 된 요약 테이블이 나타납니다. 기본적으로 가장 중요한 열만 포함되지만 쉽게 사용자 정의 할 수 있습니다. 열 세트는 적응 형이며 벤치 마크 정의 및 측정 된 값에 따라 다릅니다. 예를 들어, 벤치 마크 중 하나를 기준선으로 표시하면 모든 벤치 마크를 기준선과 비교하는 데 도움이되는 추가 열이 표시됩니다. 기본적으로 항상 평균 열을 표시하지만 평균과 중앙값 사이의 큰 차이를 감지하면 두 열이 제시됩니다.
BenchmarkDotnet은 성능 분배의 비정상적인 속성을 찾으려고 시도하고 좋은 메시지를 인쇄합니다. 예를 들어, 멀티 모달 분포 또는 높은 특이 치의 경우 경고합니다. 이 경우 결과를 스크롤하여 각 배포에 대한 ASCII 스타일 히스토그램을 확인하거나 [RPlotExporter] 사용하여 아름다운 PNG 플롯을 생성 할 수 있습니다.
BenchmarkDotnet은 데이터를 과부하시키지 않습니다. 결과에 따라 필수 정보 만 표시합니다. 원시 사례에 대한 요약을 작게 유지하고 복잡한 경우에만 확장 할 수 있습니다. 물론 추가 통계 및 시각화를 수동으로 요청할 수 있습니다. 요약보기를 사용자 정의하지 않으면 기본 프레젠테이션은 가능한 한 사용자 친화적입니다. :)
BenchmarkDotnet은 모든 벤치 마크를 마술처럼 만들고 측정을 분석하는 은색 총알이 아닙니다. 이 라이브러리를 사용하더라도 여전히 벤치 마크 실험을 설계하는 방법과 원시 데이터를 기반으로 올바른 결론을 내리는 방법을 알아야합니다. 벤치마킹 방법론 및 모범 사례에 대해 더 알고 싶다면 Andrey Akinshin (BenchmarkDotnet Project Lead)의 책을 읽는 것이 좋습니다. "Pro .NET 벤치마킹". 이 심층 가이드를 사용하여 벤치 마크를 올바르게 설계하고 .NET 응용 프로그램의 주요 성능 메트릭을 측정하며 결과를 분석하십시오. 이 책은 복잡한 벤치마킹 주제를 이해하는 데 도움이되는 수십 개의 사례 연구를 제공합니다. 일반적인 함정을 피하고 측정의 정확도를 제어하며 소프트웨어의 성능을 향상시킵니다.
BenchmarkDotnet은 이미 전문적인 수준에서 성능 조사를 수행 할 수있는 안정적인 완전한 기능 라이브러리입니다. 그리고 그것은 계속 발전하고 있습니다! 우리는 항상 새로운 기능을 추가하지만 너무 많은 새로운 멋진 아이디어가 있습니다. 모든 도움이 감사하겠습니다. 새로운 기능을 개발하거나 버그 수정, 문서를 개선하거나 다른 멋진 작업을 수행 할 수 있습니다.
기여하려면 기고 가이드 및 삭제 문제를 확인하십시오. 새로운 아이디어가 있거나 버그에 대해 불평하고 싶다면 자유롭게 새로운 문제를 만들어보십시오. 함께 벤치마킹을위한 최고의 도구를 구축합시다!
이 프로젝트는 기고자 언약이 정의한 행동 강령을 채택하여 지역 사회에서 예상되는 행동을 명확히했습니다. 자세한 내용은 .NET Foundation 행동 강령을 참조하십시오.
BenchmarkDotnet은 AWS 오픈 소스 소프트웨어 펀드에서 지원합니다.