[![](https://raw.githubusercontent.com/dotnet/BenchmarkDotNet/ec962b0bd6854c991d7a3ebd77037579165acb36/docs/logo/logo-wide.png)](https://raw.githubusercontent.com/dotnet/BenchmarkDotNet/ec962b0bd6854c991d7a3ebd77037579165acb36/docs/logo/logo-wide.png) https://benchmarkdotnet.org > **BenchmarkDotNet** helps you to transform methods into benchmarks, track their performance, and share reproducible measurement experiments. It's no harder than writing unit tests! Under the hood, it performs a lot of [magic](https://benchmarkdotnet.org/#automation) that guarantees [reliable and precise](https://benchmarkdotnet.org/#reliability) results thanks to the [perfolizer](https://github.com/AndreyAkinshin/perfolizer) and [pragmastat](https://github.com/AndreyAkinshin/pragmastat) statistical engine. BenchmarkDotNet protects you from popular benchmarking mistakes and warns you if something is wrong with your benchmark design or obtained measurements. The results are presented in a [user-friendly](https://benchmarkdotnet.org/#friendliness)form that highlights all the important facts about your experiment. BenchmarkDotNet is already adopted by [27400+ GitHub projects](https://github.com/dotnet/BenchmarkDotNet/network/dependents) including [.NET Runtime](https://github.com/dotnet/runtime), [.NET Compiler](https://github.com/dotnet/roslyn),[.NET Performance](https://github.com/dotnet/performance), and many others. BenchmarkDotNet은 .NET 애플리케이션의 코드 성능을 정확하고 쉽게 측정, 분석 및 시각화해 주는 오픈소스 벤치마킹 라이브러리. 메소드 위에 `[Benchmark]` 속성만 추가하면 실행 시간, 메모리 할당, 가비지 컬렉션(GC) 등 상세한 성능 지표를 제공하여 코드 병목 현상을 해결. ### 핵심 특징 및 기능 - **높은 정확도:** JIT 컴파일, 가비지 컬렉션 등 런타임 환경의 영향을 최소화하여 정확한 측정값을 제공 - **다양한 환경 지원:** .NET Framework, .NET Core, .NET 5+ 등 다양한 런타임에서 작동 - **상세한 분석:** 실행 시간(Mean, Median), 표준 편차, 메모리 할당(Allocated) 등 상세한 통계 보고서 생성 - **자동화된 워크플로우:** 벤치마크 프로젝트를 자동으로 생성하고 빌드하여 실행 ## 실제 실행 과정 [[2.1.1 분할 정복 알고리즘 - 퀵 정렬 관련 - 피봇 선택 방식 Benchmark]] ### Program.fs ```f# module Benchmark.Program // 모듈 선언 (Benchmark 네임스페이스 안의 Program 모듈) open BenchmarkDotNet.Running // BenchmarkRunner 사용을 위해 열기 [<EntryPoint>] // 프로그램 진입점 표시 (C#의 static void Main과 동일) let main _ = // 커맨드라인 인자는 사용 안 하므로 _ 로 무시 BenchmarkRunner.Run<PivotBenchmark>() |> ignore // PivotBenchmark 클래스의 모든 벤치마크 실행, 반환값은 무시 0 // 정상 종료 코드 반환 ``` ### Benchmark.fs ```f# namespace Benchmark // 네임스페이스 선언 (BenchmarkDotNet이 타입을 찾을 수 있도록) open BenchmarkDotNet.Attributes // [<Benchmark>] 같은 어트리뷰트 사용을 위해 열기 open QuickSort // QuickSort 모듈의 함수들 (quickSortWith 등) 사용을 위해 열기 [<MemoryDiagnoser>] // 벤치마크 실행 시 메모리 할당량(Gen0/1/2, Allocated)도 측정 type PivotBenchmark() = // 벤치마크 클래스 정의 (BenchmarkDotNet은 클래스 기반) [<Params(100, 10000, 1000000)>] // Size 파라미터를 3가지 값으로 순서대로 바꿔가며 실행 member val Size = 0 with get, set // 벤치마크 파라미터 프로퍼티 (BenchmarkDotNet이 자동으로 주입) member val Data: int list = [] with get, set // 각 Size별 테스트용 데이터 보관 [<GlobalSetup>] // 각 Size 파라미터마다 벤치마크 실행 전 한 번만 호출되는 설정 메서드 member this.Setup() = let rnd = System.Random() this.Data <- List.init this.Size (fun _ -> rnd.Next()) // Size 길이의 랜덤 int 리스트 생성. Random, MedianOfThree, MedianOfMedians에서 동일하게 사용할 수 있게 됨. [<Benchmark>] // 이 메서드를 벤치마크 측정 대상으로 등록 member this.Random() = quickSortWith selectPivotByRandom this.Data // 랜덤 피벗 전략으로 퀵소트 실행 [<Benchmark>] member this.MedianOfThree() = quickSortWith selectPivotByMedianOfThree this.Data // 3개 중앙값 피벗 전략으로 퀵소트 실행 [<Benchmark(Baseline = true)>] // 이 메서드를 기준(Ratio=1.00)으로 삼아 나머지와 상대 비교 member this.MedianOfMedians() = quickSortWith selectPivotByMedianOfMedians this.Data // 중앙값의 중앙값 피벗 전략으로 퀵소트 실행 ``` ### 실행 ```bash dotnet run -c Release --project QuickSort/Benchmark ``` - dotnet run — 프로젝트 빌드 후 바로 실행 - -c Release — Release 모드로 빌드 (필수! Debug 모드면 JIT 최적화가 안 걸려서 벤치마크 의미 없음) - --project QuickSort/Benchmark — 실행할 프로젝트 경로 지정 ## 추후 적용 가능한 포인트들 1. 같은 기능을 수행하는 여러 알고리즘들 비교하는 프로젝트 (정렬이나, 길찾기나...) 2. 벤치마크 자체를 내가 하는 스프링 웹 백엔드에 적용한다면? 1. https://0soo.tistory.com/237 처럼 JMH를 써볼 수 있을 것 같다 2. 보통 시스템 자체의 성능 테스트 - k6 사용 - 만 진행했는데, 시간이 된다면 JMH로 코드 단위의 미세 벤치마킹을 해볼 수 있을듯? 개발 단계에서 로직 성능 최적화할 때...