728x90
📘 Chapter 3.5: 코드 분석 및 성능 측정 도구 사용 (BenchmarkDotNet 등)
✅ 이 챕터에서 배울 것
- 왜 성능 측정이 중요한가
- BenchmarkDotNet 사용법 (실전 예제 포함)
- 간단한 Stopwatch 성능 측정 방법
- GC, Memory 관련 측정
- 실무 상황에서 벤치마크 전략
- 예: for vs foreach, StringBuilder vs +
1️⃣ 왜 성능 측정이 중요한가?
"느릴 것 같아서 바꿨는데, 더 느려짐"
→ 실무에서 흔한 일이다
✅ 체감 성능 ≠ 실제 성능
- 컴파일러 최적화
- GC 개입
- JIT 예열 등으로 오차 생김
→ 그러니까 정확한 측정 도구로 정량 분석해야 된다!
2️⃣ BenchmarkDotNet – .NET 성능 측정의 정석
✅ 설치
dotnet add package BenchmarkDotNet
✅ 기본 템플릿 예제
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
public class MyBenchmark
{
private List<int> _list = Enumerable.Range(0, 1000).ToList();
[Benchmark]
public void ForLoop()
{
for (int i = 0; i < _list.Count; i++)
{
var val = _list[i];
}
}
[Benchmark]
public void ForeachLoop()
{
foreach (var item in _list)
{
var val = item;
}
}
}
class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<MyBenchmark>();
}
}
✅ 실행하면 bin/Release/netX.X/BenchmarkDotNet.Artifacts
안에 결과 출력됨!
🔍 결과 예시
Method | Mean | Error | Gen 0 | Allocated |
---|---|---|---|---|
ForLoop | 2.345 us | ±0.005 | 0.00 | 0 B |
ForeachLoop | 2.158 us | ±0.004 | 0.00 | 0 B |
➡️ 오차 범위까지 포함된 정밀 결과 제공
➡️ GC 할당도 확인 가능!
3️⃣ 간단한 측정: Stopwatch
var sw = Stopwatch.StartNew();
for (int i = 0; i < 1000000; i++)
{
var x = i * 2;
}
sw.Stop();
Console.WriteLine($"⏱ 실행 시간: {sw.ElapsedMilliseconds} ms");
🟡 간단하지만:
- GC 개입
- 최적화 여부
- Warm-up 안 됨
→ 정확한 비교용으론 BenchmarkDotNet이 낫다!
4️⃣ 실전: StringBuilder vs 문자열 +
public class StringBenchmark
{
[Benchmark]
public string StringPlus()
{
string result = "";
for (int i = 0; i < 100; i++)
{
result += i;
}
return result;
}
[Benchmark]
public string UseStringBuilder()
{
var sb = new StringBuilder();
for (int i = 0; i < 100; i++)
{
sb.Append(i);
}
return sb.ToString();
}
}
✅ 대부분의 경우 StringBuilder가 훨씬 빠르다
하지만 반복 횟수가 작으면 큰 차이 안 나기도 한다
5️⃣ GC, 메모리 측정도 가능
[MemoryDiagnoser]
public class GCBenchmark
{
[Benchmark]
public void AllocateList()
{
var list = new List<int>();
for (int i = 0; i < 1000; i++)
{
list.Add(i);
}
}
}
📌 출력에 Gen0, Gen1, Allocated 값까지 포함됨
✅ 실무 팁: 벤치마크 전략
상황 | 전략 |
---|---|
성능 비교 | 반드시 BenchmarkDotNet으로 테스트 |
GC 개입 확인 | [MemoryDiagnoser] 어노테이션 추가 |
반복 횟수 적정화 | 실제 사용 상황과 유사하게 |
결과 해석 | 평균 + 표준편차 함께 보기 |
Warm-up | 초기 1~2회 측정값은 버리는게 좋음 |
✅ 정리 요약
항목 | 요약 |
---|---|
BenchmarkDotNet | 가장 정확한 .NET 벤치마킹 도구 |
Stopwatch | 빠르게 비교할 때만 사용 |
MemoryDiagnoser | GC 할당량까지 확인 가능 |
실무 적용 | 반복문, 문자열, 알고리즘 등 성능 튜닝 |
📢 다음 챕터 예고 🎓
다음 챕터 | 주제 |
---|---|
Chapter 3.6 | .NET 메모리 관리 이해 – GC 동작 원리 |
728x90
'C#' 카테고리의 다른 글
C# 기초부터 고급까지 Chapter 3.6. .NET 메모리 관리 이해 – GC 동작 원리 (0) | 2025.05.10 |
---|---|
C# 기초부터 고급까지 Chapter 3.4. 고급 LINQ 커스터마이징 & 쿼리 최적화 (2) | 2025.05.06 |
C# 기초부터 고급까지 Chapter 3.3. Expression Tree로 컴파일 타임 코드 생성 (14) | 2025.05.05 |
C# 기초부터 고급까지 Chapter 3.2. Reflection & Dynamic Type – 런타임 메타프로그래밍 (0) | 2025.05.05 |
C# 기초부터 고급까지 Chapter 3.1. Span , Memory , Unsafe – 퍼포먼스 챙기는 C# 코드 (0) | 2025.05.04 |