01
병목 확인
프로파일러가 가리킨 hot path 밖의 코드는 그대로 둔다.
02
자료 배치를 바꾼다
vector, struct layout, SoA/AoS 선택처럼 캐시가 읽는 순서를
개선한다.
03
의미를 보존한다
빠르게 만든 뒤 sanitizer, 테스트, 벤치마크로 원래 계약을 깨지
않았는지 확인한다.
copy elision
불필요한 복사 제거
반환값 최적화와 move가 적용되는 경로를 이해한다.
std::move가 RVO를 막는 경우도 있다.
reserve
재할당 감소
예상 크기를 알면 vector와 string의 growth 비용을 줄인다.
과도한 예약은 메모리 낭비다.
cache locality
가까운 데이터
연속 메모리 순회가 노드 기반 구조보다 빠른 경우가 많다.
list가 항상 삽입에 유리한 것은 아니다.
algorithmic
복잡도 개선
O(n^2)를 O(n log n)으로 줄이는 변화가 미세 최적화보다
크다.
입력 크기와 상수항을 함께 본다.
측정 전 변경 · 수명 · 정확성 점검
측정 전 변경
프로파일 없이 읽기 어려운 최적화를 먼저 넣고 있지 않은가.
수명
복사를 줄이려다 dangling reference나 moved-from 사용을 만들지
않는가.
정확성
빠른 경로와 느린 경로가 같은 결과를 낸다는 테스트가
있는가.
할당 줄이기
std::vector<Item> items;
items.reserve(input.size());
for (const auto& raw : input) {
items.emplace_back(parse(raw));
}