-
[C#] Struct vs Class, 성능 차이 진짜 날까? (언제 무엇을 쓸지 정해드립니다)개발/C# 2026. 1. 20. 11:26반응형
안녕하세요!
C#에서 대부분의 경우 우리는 class를 사용합니다. 하지만 고성능을 요구하는 게임 엔진, 대규모 데이터 처리 로직을 짜다 보면 struct가 등판할 때가 있죠. "구조체가 더 빠르다던데?"라는 막연한 생각으로 썼다가 오히려 성능이 더 떨어지는 경우도 허다합니다.
오늘은 이 둘의 성능 차이가 어디서 오는지, 그리고 **'진짜 고수'**들은 어떤 기준으로 선택하는지 정리해 드릴게요.
1. 핵심 차이: 힙(Heap)이냐 스택(Stack)이냐
가장 큰 차이는 데이터가 메모리의 어디에 저장되느냐입니다.
- Class (참조 형식): 힙(Heap) 영역에 저장됩니다. 변수에는 데이터가 있는 '주소'만 담기죠. 데이터를 쓰려면 주소를 타고 한 번 더 찾아가야 합니다.
- Struct (값 형식): 스택(Stack) 영역에 저장됩니다. 변수 자체가 데이터 그 자체입니다. 찾아갈 필요 없이 바로 꺼내 쓰면 됩니다.
여기까지만 보면 "어? 스택이 빠르니까 무조건 구조체가 좋겠네?"라고 생각하시겠지만, 진짜 문제는 **'가비지 컬렉터(GC)'**입니다.
2. 성능의 주범, 가비지 컬렉션(GC)
클래스는 힙에 생성되기 때문에 사용이 끝나면 GC가 와서 치워줘야 합니다. 수만 개의 클래스 객체를 만들었다 지웠다 하면 GC가 열일하게 되고, 이 과정에서 프로그램이 미세하게 끊기는 '프리징'이 발생하죠.
반면, 구조체는 메서드가 끝나면 스택에서 자동으로 사라집니다. GC가 신경 쓸 필요가 없다는 것, 이게 구조체가 성능상 가지는 최대 강점입니다.
3. 실제 코드와 벤치마크 (성능 체감하기)
만약 백만 개의 좌표 데이터를 생성한다면 어떤 차이가 날까요? (BenchmarkDotNet 결과 수치를 예로 들어볼게요.)
// 1. 클래스로 정의 public class PointClass { public int X; public int Y; } // 2. 구조체로 정의 public struct PointStruct { public int X; public int Y; } // [테스트 시나리오: 1,000,000개를 생성하고 리스트에 담기] // - Class: 약 15ms 소요 / GC 할당량 약 24MB // - Struct: 약 2ms 소요 / GC 할당량 0MB (!!)수치상으로 보면 구조체가 압도적으로 빠르고 메모리도 깨끗합니다. 하지만 여기서 함정이 있습니다.
4. 구조체를 쓸 때 주의할 점 (오해와 진실)
구조체가 항상 빠른 건 아닙니다. 아래 조건들을 꼭 체크하세요.
- 데이터 크기: 구조체는 값이 복사됩니다. 만약 구조체 안에 필드가 너무 많아서 크기가 커지면(보통 16바이트 이상), 함수에 전달할 때마다 무거운 데이터를 복사하느라 오히려 클래스보다 느려집니다.
- 불변성(Immutability): 구조체는 값을 바꿀 때 조심해야 합니다. 웬만하면 readonly struct로 만들어서 값을 못 바꾸게 관리하는 게 버그를 줄이는 지름길입니다.
- 박싱(Boxing): 구조체를 object 타입으로 바꾸거나 인터페이스로 받으면 다시 힙으로 올라가버립니다(박싱). 이러면 구조체를 쓰는 의미가 아예 사라집니다.
이럴 땐 Class 쓰세요. 이럴 떈 Struct 쓰세요. 데이터 크기가 크고 복잡할 때 데이터가 작고 단순할 때(예: 좌표, 색상, 금액) 객체의 생명 주기가 길때 잠깐 쓰고 버려지는 짧은 로직일 때 상속(Inheritance) 기능이 필요할 때 성능 최적화가 극도로 중요할 때 (GC 부하 감소) 기본적으로는 Class가 정답입니다. 논리적으로 하나의 '값'처럼 취급될 때 마무리하며 결국 성능 최적화의 핵심은 **"메모리를 얼마나 덜 어지럽히느냐(GC 부하를 줄이느냐)"**에 있습니다. 무조건 구조체를 고집하기보다, 상황에 맞춰 적재적소에 사용하는 것이 진짜 실력입니다!
오늘 포스팅이 도움 되셨나요? 궁금한 점이나 여러분만의 팁이 있다면 댓글로 공유해 주세요!
반응형'개발 > C#' 카테고리의 다른 글
C# 설계의 핵심: 인터페이스 vs 추상 클래스, 5분 만에 끝내는 완벽 비교 (0) 2026.01.23 [C#] "파일을 찾을 수 없습니다" – FileNotFoundException, 경로의 함정 (1) 2026.01.22 C# foreach 돌리다 터지는 '열거 작업 수정' 에러, 해결 가이드Enumerable was modified (0) 2026.01.19 [C#] WinForms "크로스 스레드 작업이 잘못되었습니다" (0) 2026.01.15 C# 비동기 프로그래밍(async/await) (1) 2026.01.14