Modern C++ 기능이란 C++17/20/23에서 도입된 ranges, concepts, modules 등 성능·표현력에 영향을 주는 기능을 말합니다. 본 챕터에서는 이들의 비용과 이점을 정리하고, Low-latency 코드에서 활용할 때 측정·기준을 다룹니다.
이 장을 읽기 전에
완전한 초보자? 이 장은 08장: 템플릿/constexpr의 컴파일 타임 개념을 전제로 합니다. C++17/20/23이라는 표준 버전 구분과 ranges·concepts가 “표현력을 위한 기능"이라는 정도만 알면 충분합니다.
이 장의 깊이: 이 장은 중급~전문가를 포괄합니다. ranges·concepts·modules의 성능 특성을 정리하는 것부터 시작해, 전문가 구간에서는 ranges 파이프라인이 인라인되는지, concepts가 런타임 비용 없이 제약만 거는지 등 “표현력 vs 런타임 비용"을 구분하는 기준을 다룹니다. 다루지 않는 것: 모듈의 빌드 시스템 통합 세부(Tr.02 컴파일러 트랙)와 코루틴(10장)입니다.
당신의 수준에 맞는 경로
| 수준 | 읽을 부분 | 핵심 목표 |
|---|---|---|
| 초보자 | “Ranges (C++20)” ~ “Concepts (C++20)” | 기능의 목적과 런타임 비용 유무 이해 |
| 중급자 | “Modules (C++20)” ~ “기타 C++17/20/23 기능 (성능 관점)” | 핫패스에 쓸지 측정으로 판단 |
| 전문가 | “판단 기준” ~ “비판적 시각” | 표현력과 성능의 트레이드오프 선택 |
C++17/20/23 성능 관련 기능 (역사·배경)
Ranges는 C++20에서 표준에 들어왔고, 범위 기반 연산과 뷰·지연 평가를 제공합니다. Concepts도 C++20에서 도입되어 템플릿 제약을 타입 시스템으로 표현합니다. Modules는 C++20에서 표준화되어 헤더 대신 모듈 단위로 인터페이스를 나누어 컴파일 시간과 노출 범위를 줄입니다. 각 기능은 “표현력·안전성·빌드"에 이점이 있으나, Low-latency에서는 런타임 오버헤드가 있는지(예: ranges 파이프라인 인라인, concepts의 런타임 비용 없음)를 구분해 핫패스에 쓸지 결정해야 합니다.
“A range is a sequence of elements that can be iterated. A view is a non-owning range that is O(1) to copy and move.” — cppreference (std::ranges). 뷰는 복사가 저렴하고 지연 평가되므로, 파이프라인으로 연결해도 중간 컨테이너 할당을 줄일 수 있습니다.
Ranges (C++20)
Ranges 라이브러리는 **범위(range)**를 인자로 두고, **뷰(view)**를 파이프 |로 연결해 연산을 표현합니다. 많은 뷰는 지연 평가되어 최종적으로 소비(순회·수집)될 때만 연산이 실행됩니다. 뷰는 대체로 복사 없이 원본 범위를 참조하므로 중간 컨테이너 할당을 줄일 수 있습니다.
뷰를 파이프 |로 연결하면 중간 결과 없이 최종 소비 시점에만 연산이 실행됩니다.
| |
ranges vs 수동 루프: 위 파이프라인은 다음 for 루프와 동일한 결과를 냅니다.
| |
선언적 파이프라인은 가독성이 좋지만, 구현체·최적화 수준에 따라 어댑터 객체와 반복자 래핑이 충분히 인라인되지 않으면 µs 경로에서 오버헤드가 보일 수 있습니다. 핫패스에서는 두 버전을 같은 알고리즘으로 벤치마크해 오버헤드가 허용 범위인지 확인한 뒤 사용하는 것이 안전합니다.
Concepts (C++20)
Concepts는 템플릿 파라미터에 제약을 걸어, 컴파일 타임에 타입이 요구사항을 만족하는지 검사합니다. 에러 메시지가 명확해지고 오버로드 해석이 더 잘 짜이며, 만족하는 타입에 대해서는 기존 템플릿과 동일하게 인라인·최적화되어 추가 런타임 오버헤드가 없습니다.
아래는 template<std::integral T> 단축 표기와 requires 절을 함께 보여 줍니다.
| |
성능 트랙에서는 “concepts는 컴파일 타임 제약일 뿐 런타임 비용이 없다"는 점을 인지하고, 표현력·검사용으로 활용합니다.
Modules (C++20)
Modules는 번역 단위 단위로 인터페이스와 구현을 나누어, 헤더를 반복 파싱하지 않고 컴파일 시간을 줄이고 빌드 캐시를 활용할 수 있게 합니다. 모듈에서 export한 선언만 보이므로 노출 범위가 작아져 인라인·최적화 경계가 더 예측 가능해질 수 있습니다.
| |
| |
다만 아직 구현체·빌드 시스템·도구 지원이 플랫폼마다 다르므로(모듈 인터페이스 확장자·빌드 플래그가 컴파일러마다 상이함), 도입 시 빌드 설정과 성능을 프로젝트에서 측정해 보는 것이 좋습니다.
기타 C++17/20/23 기능 (성능 관점)
- if constexpr: 컴파일 타임에 분기가 결정되므로 선택되지 않은 경로의 코드는 생성되지 않고 런타임 분기도 없습니다. 템플릿 안에서 타입·상수에 따라 다른 구현을 택할 때 유용합니다(챕터 08 참고).
- 구조화된 바인딩: 튜플·구조체 멤버를 바인딩할 때 복사/참조를 명시할 수 있어 불필요한 복사를 줄이기 쉽습니다.
- [[likely]] / [[unlikely]]: 분기 예측 힌트로, CPU가 해당 경로를 선호하도록 할 수 있습니다. 효과는 플랫폼·컴파일러에 따라 다르므로 중요한 경로에만 쓰고 벤치마크로 확인합니다.
- std::format, constexpr 확장: 포맷·문자열 처리와 constexpr 가능 범위가 넓어져, 상수 문자열 생성·포맷을 컴파일 타임에 처리할 수 있는 경우가 늘었습니다.
평가 기준 (학습 성과 목표)
- Ranges의 지연 평가·뷰(non-owning) 특성을 설명하고, 핫패스에서 벤치마크 후 오버헤드가 허용되는지 판단할 수 있다.
- Concepts가 런타임 오버헤드 없이 컴파일 타임 제약만 추가함을 설명하고,
template<std::integral T>·requires절을 작성할 수 있다. - Modules가 컴파일 시간·노출 범위에 미치는 영향을 설명하고, 도입 시 빌드·성능을 측정할 수 있다.
- if constexpr, 구조화된 바인딩, [[likely]]/[[unlikely]] 등이 성능에 미치는 맥락을 구분할 수 있다.
판단 기준 (언제 쓸고 언제 피할지)
| 상황 | 권장 | 비권장 |
|---|---|---|
| ranges 파이프라인 | 벤치마크 후 오버헤드 허용 시 | µs 경로에 무검증 도입 |
| 템플릿 제약 | concepts로 가독성·에러 메시지 개선 | 런타임 비용 기대 (없음) |
| 빌드 시간·모듈화 | modules 실험·측정 후 도입 | 도구 미지원 환경에서 강제 |
적용 체크리스트: (1) 핫패스에 ranges 넣기 전 동일 알고리즘으로 벤치마크. (2) concepts는 표현력·검사용, 런타임 비용 없음 인지. (3) [[likely]]/[[unlikely]]는 중요 경로에만, 효과는 측정으로 확인.
비판적 시각: 한계와 트레이드오프
- Ranges: 구현체·최적화에 따라 파이프라인 오버헤드가 있을 수 있다. “무조건 for 루프"가 아니라, 가독성과 성능을 벤치마크로 맞보는 것이 합리적이다.
- Modules: 빌드 시스템·컴파일러 지원이 아직 불균일하므로, 프로젝트별로 도입 가능 여부와 이득을 평가해야 한다.
핵심 요약
| 항목 | 요약 |
|---|---|
| Ranges | 지연 평가·뷰, 중간 할당 감소; 핫패스는 벤치마크 후 사용 |
| Concepts | 컴파일 타임 제약, 런타임 오버헤드 없음 |
| Modules | 컴파일 시간·노출 감소, 도구 지원 확인 필요 |
| 기타 | if constexpr·구조화 바인딩·[[likely]] 등 상황별 활용 |
용어 정리
| 용어 | 설명 |
|---|---|
| range | 순회 가능한 요소 시퀀스; C++20 std::ranges |
| view | non-owning, 복사 O(1), 지연 평가되는 range |
| concept | 템플릿 파라미터 제약; 컴파일 타임 검사, 런타임 비용 없음 |
| module | 헤더 대체; export한 선언만 노출, 빌드 시간·노출 감소 |
벤치마크 결과 해석 가이드
| 관찰 | 해석·다음 단계 |
|---|---|
| ranges 파이프라인이 for 루프보다 느림 | 구현체·컴파일러에 따라 다름; 동일 알고리즘으로 벤치마크 후 도입 |
| concepts 도입 후 런타임 차이 없음 | 정상; concepts는 컴파일 타임 제약, 런타임 오버헤드 없음 |
| modules 도입 후 빌드 시간 감소 | 컴파일 시간 절감; 도구 지원 확인 |
자주 묻는 질문 (FAQ)
Q: ranges가 항상 for 루프보다 느리나요?
A: 구현체·최적화에 따라 다릅니다. 동일 알고리즘으로 벤치마크한 뒤, 허용 가능한 오버헤드일 때만 핫패스에 도입합니다.
Q: concepts는 런타임 비용이 있나요?
A: 없습니다. 컴파일 타임 제약만 추가되므로, 가독성·에러 메시지 개선용으로 사용합니다.
Q: modules를 지금 도입해야 하나요?
A: 빌드 시스템·컴파일러 지원이 프로젝트마다 다릅니다. 실험·측정 후 도입 가능 여부를 평가합니다.
적용 체크리스트 (실무용)
- 핫패스에 ranges를 넣기 전 동일 알고리즘으로 벤치마크했는가?
- concepts는 런타임 비용 없음을 인지하고 가독성·에러 메시지용으로 썼는가?
- modules 도입 시 도구 지원·빌드 시간을 확인했는가?
- [[likely]]/[[unlikely]]는 효과를 측정한 뒤 적용했는가?
- 변경 후 벤치마크·빌드 시간으로 회귀 검증했는가?
진단 도구 요약
| 목적 | 도구·방법 |
|---|---|
| ranges vs for 성능 | 격리 벤치마크(동일 알고리즘) |
| concepts | 런타임 비용 없음; 컴파일 시간만 확인 |
| modules | 빌드 시간 측정, 도구 지원 확인 |
자주 하는 실수
- ranges를 핫패스에 무검증 도입: 벤치마크 후 오버헤드가 허용될 때만 도입합니다.
- concepts에 런타임 비용 기대: concepts는 컴파일 타임만; 런타임 비용 없음.
- modules를 도구 미지원 환경에서 강제: 지원 여부와 빌드 시간 이득을 먼저 확인합니다.
리팩토링 시 주의
기존 for 루프를 ranges로 바꿀 때 동일 알고리즘인지 확인하고, 벤치마크로 회귀가 없는지 검증합니다. modules 도입 시 include 순서·헤더 노출이 바뀌므로 빌드·테스트를 충분히 수행합니다.
추가 읽기 및 관련 챕터
- 챕터 08 (템플릿/constexpr): 컴파일 타임 전략과 연계.
- 챕터 10 (코루틴): C++20 비동기 기능.
- 챕터 14 (span과 뷰): 뷰 패턴·non-owning.
다음 장에서는
이전 장: 템플릿/constexpr (챕터 08)
코루틴 성능을 다룹니다. C++20 코루틴의 suspend/resume 비용, 프레임 할당, 저지연 경로에서의 활용 기준을 정리합니다. → 코루틴 성능 (챕터 10)
![Featured image of post [Optimization(C++) 09] Modern C++ 기능](/post/cpp-optimization/modern-cpp-features/wordcloud_hu_95806e2010771378.webp)
![[Optimization(C++) 07] 임시 객체 제거](/post/cpp-optimization/temporary-removal/wordcloud_hu_f763a659505ec6fc.webp)
![[Optimization(C++) 08] 템플릿/constexpr](/post/cpp-optimization/templates-constexpr/wordcloud_hu_652387c722476f19.webp)
![[Optimization(C++) 09] Modern C++ 기능](/post/cpp-optimization/modern-cpp-features/wordcloud_hu_82b9f8d4f98733a.webp)
![[Optimization(C++) 10] 코루틴 성능](/post/cpp-optimization/coroutine-performance/wordcloud_hu_57d450707cfb1c79.webp)
![[Optimization(C++) 11] 예외 처리 심화](/post/cpp-optimization/exception-deep-dive/wordcloud_hu_c542384a35b5a871.webp)
![[Rust] Comprehensive Rust 무료 강의 정리 및 코스 구조](/post/2022-12-30-comprehensive-rust/wordcloud_hu_d1420ff38434cdb6.webp)
![[Hardware] LattePanda Alpha에 Ubuntu 16.04 LTS 설치 가이드](/post/2018-12-06-install-ubuntu-16.04-on-lattepanda/wordcloud_hu_fc536f8de2cbd4bf.webp)
![[Optimization(C++) 13] std::variant/optional/expected](/post/cpp-optimization/variant-optional-expected/wordcloud_hu_b06d8ae673ab76c5.webp)
![[Optimization(C++) 16] Small Buffer Optimization](/post/cpp-optimization/small-buffer-optimization/wordcloud_hu_9326fd48e244893f.webp)
![[Optimization(C++) 17] Parameter Passing 전략](/post/cpp-optimization/parameter-passing/wordcloud_hu_a07c02ecf5f0707a.webp)