C# 에서 BenchmarkDotNet을 사용하여 성능 테스트(가비지 할당관련) 를 하고 있었는데
가비지 나오는게 뭔가 이상하다 싶어서 for 문에서 iteratoin 값을 1억에서 10만번으로 바꿨더니 가비지가 나오지 않습니다.
for 문만 1억번 돌렸을때도 가비지가 나옵니다. 이유가 무엇일까요. 따른 거 없이 for문만 돌렸습니다.

(1억번돌렸을때 결과)

(10만번돌렸으때 결과)
아래는 소스코드입니다.
using BenchmarkDotNet.Attributes;
using System;
using BenchmarkDotNet.Running;
namespace Empty
{
//[ShortRunJob]
[MemoryDiagnoser]
public class Program
{
public static void Main()
{
BenchmarkRunner.Run();
}
public interface ITest
{
public void Haha();
}
public struct TestStruct : ITest
{
public void Haha() { }
}
[Benchmark]
public void BenchmarkFunction()
{
const int k_iterationCount = 100_000_000; //가비지 발생.
//const int k_iterationCount = 100000; //가비지 발생 안함.
for (int i = 0; i < k_iterationCount; i++)
{
//GarbageTest(new TestStruct());
}
}
public static void GarbageTest(T t) where T : struct, ITest
{
//t.Haha();
}
public static void Gar2(TestStruct t)
{
//t.Haha();
}
}
}
2개의 좋아요
저는 BenchmarkDotNet은 안 써봤습니다만, 주신 코드를 약간 수정해서 그대로 돌려봤습니다.
소스코드를 붙혀 넣으시다 실수하신 게 아닌가 생각되지만 주신 코드를 바로 적용하면 컴파일 에러가 발생합니다. 그래서 아래 코드를 수행했습니다. 이런 마크다운 기반의 포럼에서 코드를 인용해 주실 때는 마크다운으로 코드를 인용하는 방법이 있으니 사용해보시면 더욱 정확하게 질문을 남기실 수 있을 듯합니다.
테스트 환경
- .NET 9
- BenchmarkDotNet 0.15.2
using BenchmarkDotNet.Attributes;
using System;
using BenchmarkDotNet.Running;
namespace Empty
{
//[ShortRunJob]
[MemoryDiagnoser]
public class Program
{
public static void Main()
{
BenchmarkRunner.Run<Program>();
}
public interface ITest
{
public void Haha();
}
public struct TestStruct : ITest
{
public void Haha()
{
}
}
[Benchmark]
public void BenchmarkFunction()
{
//const int k_iterationCount = 100_000_000; //가비지 발생.
const int k_iterationCount = 100000; //가비지 발생 안함.
for (int i = 0; i < k_iterationCount; i++)
{
//GarbageTest(new TestStruct());
}
}
public static void GarbageTest<T>(T t) where T : struct, ITest
{
//t.Haha``();
}
public static void Gar2(TestStruct t)
{
//t.Haha``();
}
}
}
결론적으로 저는 가비지라고 말씀하신 부분이 발생하지 않았습니다.
그리고 가비지가 아니고 Allocated는 할당된 메모리라 가비지 수집한 내용이 아닌 것으로 알고 있어서 표현에도 약간 오해가 발생할 여지가 있다고 생각합니다.
1억번 수행 화면
10만번 수행 화면
아래 글을 읽어보면 벤치마크를 측정하는 팁이 있는 것 같습니다.
.NET 벤치마크가 거짓말을 하는 이유(+ 해결 방법) | by 호세인 코자디 | 잇넥스트
- 디버그 모드에서 벤치마크 하지 말 것. (실제로 제 화면도 Release에서 ‘디버그 없이 시작’을 했습니다.)
- 벤치마크 단계에서 뭔가 설정할 거 하지 말 것. (밴치마크가 시작되기 이전에 설정을 미리 해둘 것)
- 적게 반복하면 신뢰 불가능
- MemoryDiagnoserAttribute 사용할 것.
- 비교할 수 있는 기준선을 제시하여 ‘~ 대비하여 ~% 만큼 개선되었음’ 을 명시하도록 할 것
- StdDev는 뭔지 잘 모르겠네요
- 실제로 측정할 값과 유사하지 않은 엉뚱한 값을 사용하지 말 것. (이건 모든 테스트의 기본이죠)
5개의 좋아요
그리고 가비지가 아니고 Allocated는 할당된 메모리.. // 잘못말햇습니다. 할당 메모리맞습니다.
혹시나 해서 BenchmarkDotNet 을 업데이트 했는데 고쳐졌습니다. 0.14버전엔 문제가 있나 보네요. 감사합니다.
2개의 좋아요