0Pricing
C# Academy · 강의

BenchmarkDotNet을 사용한 벤치마킹

BenchmarkDotNet으로 정확한 마이크로 벤치마크를 작성하고 처리량과 할당을 분석하며 일반적인 함정을 피합니다.

BenchmarkDotNet을 사용한 벤치마킹은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

BenchmarkDotNet이 필요한 이유

마이크로 벤치마킹은 생각보다 어렵습니다. JIT 워밍업, 가비지 컬렉션 일시 중지, CPU 캐시 및 운영 체제 스케줄링이 모두 잡음을 발생시킵니다. BenchmarkDotNet은 이 모든 과정을 자동으로 처리하고 통계적으로 신뢰할 수 있는 결과를 생성합니다.

설치 및 첫 번째 벤치마크

NuGet 패키지를 추가하고, [Benchmark] 메서드가 있는 클래스를 만든 다음 BenchmarkRunner.Run으로 실행하십시오. 벤치마크는 항상 Release 모드에서 실행하십시오.

// dotnet add package BenchmarkDotNet

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

[MemoryDiagnoser]           // report allocations
[RankColumn]                // rank methods by speed
public class StringBenchmarks
{
    [Benchmark(Baseline = true)]
    public string Concatenation()
    {
        var s = "";
        for (int i = 0; i < 100; i++) s += i;
        return s;
    }

    [Benchmark]
    public string StringBuilder()
    {
        var sb = new System.Text.StringBuilder();
        for (int i = 0; i < 100; i++) sb.Append(i);
        return sb.ToString();
    }
}

// Program.cs (must run as Release):
BenchmarkRunner.Run<StringBenchmarks>();

결과 표 읽기

BenchmarkDotNet은 평균 시간, 오류, 표준 편차, 비율 및 메모리 할당량이 포함된 결과 표를 출력합니다. 각 열을 해석하는 방법을 알아보겠습니다.

// Example output:
// | Method        |     Mean |   Error |  StdDev | Ratio | Alloc |
// |-------------- |---------:|--------:|--------:|------:|------:|
// | Concatenation | 4,210 ns |  81 ns  |  76 ns  |  1.00 | 6.4KB |
// | StringBuilder |   312 ns |   4 ns  |   4 ns  |  0.07 | 1.6KB |

// Mean:  average time per operation
// Error: half of 99.9% confidence interval
// StdDev: standard deviation — high value = noisy environment
// Ratio: relative to Baseline=true method (1.00)
// Alloc: managed heap allocated per operation

// Rule of thumb:
// Error should be < 5% of Mean for reliable results
// Run on an isolated machine (no background tasks)

매개 변수화된 벤치마크

[Params]를 사용하여 여러 입력 크기에 걸쳐 벤치마크를 실행하십시오. BenchmarkDotNet은 모든 조합을 실행하고 각 매개 변수 값마다 별도의 행을 생성합니다.

[MemoryDiagnoser]
public class SearchBenchmarks
{
    [Params(10, 100, 1000, 10000)]
    public int N;

    private int[] _data = Array.Empty<int>();

    [GlobalSetup]
    public void Setup()
        => _data = Enumerable.Range(0, N).ToArray();

    [Benchmark]
    public bool LinearSearch()
        => Array.IndexOf(_data, N - 1) >= 0;

    [Benchmark]
    public bool BinarySearch()
        => Array.BinarySearch(_data, N - 1) >= 0;
}

설정 및 정리

수명 주기 특성을 사용하여 한 번만 수행하는 설정 또는 반복마다 수행하는 설정과 정리를 실행하십시오. 이렇게 하면 설정 비용이 측정된 벤치마크 시간에 포함되지 않습니다.

[MemoryDiagnoser]
public class DbQueryBenchmarks
{
    private NpgsqlConnection _conn = null!;
    private NpgsqlCommand _cmd = null!;

    [GlobalSetup]              // runs once before all benchmarks
    public void Setup()
    {
        _conn = new NpgsqlConnection("...");
        _conn.Open();
        _cmd = new NpgsqlCommand("SELECT id FROM orders LIMIT 100", _conn);
    }

    [IterationSetup]           // runs before EACH benchmark iteration
    public void IterationSetup() { /* per-iteration prep */ }

    [Benchmark]
    public int QueryOrders() => (int)_cmd.ExecuteScalar()!;

    [GlobalCleanup]            // runs once after all benchmarks
    public void Cleanup() { _cmd.Dispose(); _conn.Dispose(); }
}

메모리 진단

[MemoryDiagnoser]는 작업당 관리 힙 할당량을 보고합니다. [GcForce] 옵션과 함께 사용하여 벤치마크 중 가비지 컬렉션 동작을 제어하십시오.

[MemoryDiagnoser]  // adds Alloc column to results
public class AllocationBenchmarks
{
    [Benchmark]
    public int[] AllocateArray() => new int[1000];

    [Benchmark]
    public Span<int> UseStackalloc()
    {
        Span<int> span = stackalloc int[1000];
        return span; // WARN: for illustration; don't return stackalloc
    }

    [Benchmark]
    public int[] ArrayPoolRent()
    {
        var arr = System.Buffers.ArrayPool<int>.Shared.Rent(1000);
        System.Buffers.ArrayPool<int>.Shared.Return(arr);
        return arr;
    }
}

진단기: ETW 및 디스어셈블리

BenchmarkDotNet은 여러 진단기를 지원합니다. DisassemblyDiagnoser는 실제 네이티브 어셈블리 출력을 보여 주므로 JIT 최적화를 확인하는 데 적합합니다.

using BenchmarkDotNet.Diagnosers;

[DisassemblyDiagnoser(          // show generated ASM
    maxDepth: 2,
    printSource: true,
    exportGithubMarkdown: true)]
[MemoryDiagnoser]
public class VectorizationBenchmarks
{
    private float[] _data = new float[1024];

    [Benchmark]
    public float SumScalar()
    {
        float sum = 0;
        foreach (var v in _data) sum += v;
        return sum;
    }

    [Benchmark]
    public float SumVectorized()
        => System.Numerics.Vector<float>.Count > 1
            ? VectorSum(_data)
            : SumScalar();
}

작업 구성

작업은 벤치마크 실행 환경을 제어합니다. 워밍업 반복 횟수, 반복당 호출 횟수, .NET 런타임 버전 및 JIT 설정을 지정할 수 있습니다. 미리 정의된 작업이나 사용자 지정 작업을 사용하십시오.

using BenchmarkDotNet.Jobs;

// Compare JIT vs Native AOT performance:
[SimpleJob(RuntimeMoniker.Net90)]    // .NET 9 JIT
[SimpleJob(RuntimeMoniker.NativeAot90)] // .NET 9 AOT
[MemoryDiagnoser]
public class RuntimeComparison
{
    [Benchmark]
    public string SerializeJson()
    {
        var obj = new { Name = "Alice", Age = 30 };
        return System.Text.Json.JsonSerializer.Serialize(obj);
    }
}

// Custom job for more warmup:
[Config(typeof(MyConfig))]
public class PreciseBenchmarks
{
    private class MyConfig : ManualConfig
    {
        public MyConfig()
            => AddJob(Job.Default.WithWarmupCount(5).WithIterationCount(20));
    }
}

결과 내보내기

BenchmarkDotNet은 여러 형식으로 결과를 내보냅니다. Markdown(GitHub PR용), CSV(스프레드시트용), JSON 및 HTML 차트를 지원합니다. 내보내기 옵션은 작업 구성에서 설정합니다.

using BenchmarkDotNet.Exporters;
using BenchmarkDotNet.Exporters.Csv;

[Config(typeof(ExportConfig))]
public class MyBenchmarks { /* ... */ }

public class ExportConfig : ManualConfig
{
    public ExportConfig()
    {
        AddExporter(MarkdownExporter.GitHub);
        AddExporter(CsvExporter.Default);
        AddExporter(HtmlExporter.Default);
        // Results in: BenchmarkDotNet.Artifacts/results/
    }
}

// CLI usage to run specific benchmarks:
// dotnet run -c Release -- --filter "*StringBenchmarks*"
// dotnet run -c Release -- --list all  (list all benchmarks)

실전: 최적화 전후 비교

성능 최적화를 검증하기 위해 BenchmarkDotNet을 사용하여 단순한 방식, 풀 사용 방식 및 Span 기반 접근 방식을 비교합니다.

[MemoryDiagnoser]
[RankColumn]
public class ParsingBenchmarks
{
    private const string Input = "2025-06-15T08:30:00Z";

    [Benchmark(Baseline = true)]
    public DateTime ParseViaString()
        => DateTime.Parse(Input);

    [Benchmark]
    public DateTime ParseExact()
        => DateTime.ParseExact(Input,
            "yyyy-MM-ddTHH:mm:ssZ",
            System.Globalization.CultureInfo.InvariantCulture);

    [Benchmark]
    public bool TryParse()
        => DateTime.TryParseExact(Input.AsSpan(),
            "yyyy-MM-ddTHH:mm:ssZ",
            System.Globalization.CultureInfo.InvariantCulture,
            System.Globalization.DateTimeStyles.None,
            out _);
}

빠른 확인

BenchmarkDotNet 벤치마크를 dotnet run -c Release로 실행해야 하는 이유는 무엇입니까?

복습: BenchmarkDotNet을 사용한 벤치마킹

핵심 요점:

  • NuGet을 통해 설치하고, [Benchmark]로 메서드를 표시한 다음 dotnet run -c Release로 실행하십시오
  • [MemoryDiagnoser]: 할당 열을 추가합니다. [RankColumn]: 속도순으로 순위를 지정합니다
  • [Params]: 여러 입력 크기에 걸쳐 실행하여 알고리즘의 복잡도를 확인합니다
  • [GlobalSetup] / [GlobalCleanup]: 측정 시간에 포함되지 않는 한 번만 수행하는 설정입니다
  • [DisassemblyDiagnoser]: 생성된 네이티브 ASM을 검사하여 JIT 최적화를 확인합니다
  • 작업을 사용하여 .NET 9의 JIT와 네이티브 AOT 및 서로 다른 반복 횟수를 비교하십시오

자주 묻는 질문

“BenchmarkDotNet을 사용한 벤치마킹” 강의는 무료인가요?

네 — “BenchmarkDotNet을 사용한 벤치마킹” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“BenchmarkDotNet을 사용한 벤치마킹”에서 뭘 배우나요?

BenchmarkDotNet으로 정확한 마이크로 벤치마크를 작성하고 처리량과 할당을 분석하며 일반적인 함정을 피합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C# Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“BenchmarkDotNet을 사용한 벤치마킹” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 네이티브 AOT 컴파일
  2. 트리밍과 리플렉션의 제한 사항
  3. ReadyToRun과 계층형 컴파일
  4. BenchmarkDotNet을 사용한 벤치마킹
← C# Academy(으)로 돌아가기