C++ 최적화: 최고 성능을 구현하는 10가지 검증된 기법

Book description

빠른 코드를 작성하는 시간은 느린 코드를 작성하는 시간보다 결코 길지 않다. 이 책은 올바른 코드를 구현하면서도 빠른 C++ 프로그램을 만드는 최적화 방법을 소개한다. 습관적으로 쓰는 C++ 구문을 점검해보고 싶다면 35년 경력의 저자가 소개하는 10가지 기법으로 시작해보자. 자원을 소비하고 실행 시간을 잡아먹는 부분을 찾아내 개선하다 보면 “와, 정말 빠른데! 누가 고쳤지?!”라는 말을 듣게 될지도 모른다. 실제 사례에 기반한 실용적인 팁으로 진정한 프로가 되어보자.

Table of contents

  1. C++ 최적화
    1. 지은이 옮긴이 소개
    2. 옮긴이의 말
    3. 이 책에 대하여 (1/4)
    4. 이 책에 대하여 (2/4)
    5. 이 책에 대하여 (3/4)
    6. 이 책에 대하여 (4/4)
  2. Chapter 1 최적화란
    1. 1.1 최적화는 소프트웨어 개발의 일부입니다
    2. 1.2 최적화는 효과적입니다
    3. 1.3 최적화해도 괜찮습니다
    4. 1.4 여기에 나노초, 저기에 나노초
    5. 1.5 C++ 코드 최적화 전략 요약
      1. 1.5.1 더 좋은 컴파일러를 더 잘 사용하세요
      2. 1.5.2 더 좋은 알고리즘을 사용하세요
      3. 1.5.3 더 좋은 라이브러리를 사용하세요
      4. 1.5.4 메모리 할당과 복사 줄이기
      5. 1.5.5 계산 제거하기
      6. 1.5.6 더 좋은 자료구조 사용하기
      7. 1.5.7 동시성 증가시키기
      8. 1.5.8 메모리 관리자 최적화하기
    6. 1.6 마치며
  3. Chapter 2 컴퓨터 하드웨어와 최적화
    1. 2.1 C++은 컴퓨터의 거짓말을 믿습니다
    2. 2.2 컴퓨터의 진실
      1. 2.2.1 메모리는 느립니다
      2. 2.2.2 메모리는 워드 단위로 접근합니다
      3. 2.2.3 메모리마다 접근 속도가 다릅니다
      4. 2.2.4 워드를 저장하는 방법에는 빅 엔디언과 리틀 엔디언이 있습니다
      5. 2.2.5 메모리는 한정된 자원입니다
      6. 2.2.6 명령 실행은 느립니다
      7. 2.2.7 컴퓨터는 의사 결정을 잘 하지 못합니다
      8. 2.2.8 프로그램 실행에는 여러 스트림이 있습니다
      9. 2.2.9 운영체제 기능을 호출하는 비용은 높습니다
    3. 2.3 C++도 거짓말을 합니다
      1. 2.3.1 문장의 비용이 똑같이 높지는 않습니다
      2. 2.3.2 문장은 순서대로 실행되지 않습니다
    4. 2.4 마치며
  4. Chapter 3 성능 측정
    1. 3.1 사고방식 최적화
      1. 3.1.1 성능은 반드시 측정해야 합니다
      2. 3.1.2 최적화를 하는 사람은 맹수 사냥꾼입니다
      3. 3.1.3 90/10 규칙
      4. 3.1.4 암달의 법칙
    2. 3.2 실험 수행
      1. 3.2.1 연구 노트를 보관하세요
      2. 3.2.2 성능 측정 기준과 목표 설정
      3. 3.2.3 측정한 것만 개선할 수 있습니다
    3. 3.3 프로그램 실행 프로파일
    4. 3.4 시간이 오래 걸리는 코드
      1. 3.4.1 측정 시간 ‘조금’ 배우기 (1/2)
      2. 3.4.1 측정 시간 ‘조금’ 배우기 (2/2)
      3. 3.4.2 컴퓨터로 시간 측정하기 (1/2)
      4. 3.4.2 컴퓨터로 시간 측정하기 (2/2)
      5. 3.4.3 측정 장애물 극복하기
      6. 3.4.4 스톱워치 클래스 만들기 (1/2)
      7. 3.4.4 스톱워치 클래스 만들기 (2/2)
      8. 3.4.5 테스트 하네스에서 실행 시간이 긴 함수 측정하기
    5. 3.5 코드 비용 추정하기
      1. 3.5.1 C++ 문장의 비용 추정하기
      2. 3.5.2 반복문의 비용 추정하기
    6. 3.6 최적화할 코드를 찾는 다른 방법
    7. 3.7 마치며
  5. Chapter 4 문자열 최적화
    1. 4.1 문자열이 왜 문제인가요
      1. 4.1.1 문자열은 메모리를 동적으로 할당합니다
      2. 4.1.2 문자열은 값입니다
      3. 4.1.3 문자열은 복사를 많이 합니다
    2. 4.2 문자열 최적화 첫 번째 시도
      1. 4.2.1 문자열의 내용을 변경하는 연산자로 임시 문자열 제거하기
      2. 4.2.2 저장 공간을 예약해 재할당 줄이기
      3. 4.2.3 문자열 인수의 복사 제거하기
      4. 4.2.4 반복자로 포인터 역참조 제거하기
      5. 4.2.5 반환된 문자열 값의 복사 제거하기
      6. 4.2.6 문자열 대신 문자 배열 사용하기
      7. 4.2.7 첫 번째 최적화 시도 요약
    3. 4.3 문자열 최적화 두 번째 시도
      1. 4.3.1 더 좋은 알고리즘을 사용하세요
      2. 4.3.2 더 좋은 컴파일러를 사용하세요
      3. 4.3.3 더 좋은 문자열 라이브러리를 사용하세요
      4. 4.3.4 더 좋은 할당자를 사용하세요
    4. 4.4 문자열 변환 연산 제거하기
      1. 4.4.1 C 문자열에서 std::string으로 변환
      2. 4.4.2 문자 인코딩 사이의 변환
    5. 4.5 마치며
  6. Chapter 5 알고리즘 최적화
    1. 5.1 알고리즘의 시간 비용
      1. 5.1.1 최선의 경우, 최악의 경우, 평균의 경우 시간 비용
      2. 5.1.2 상환 시간 비용
      3. 5.1.3 기타 비용
    2. 5.2 검색과 정렬을 최적화하는 툴킷
    3. 5.3 효율적인 검색 알고리즘
      1. 5.3.1 검색 알고리즘의 시간 비용
      2. 5.3.2 모든 검색 알고리즘은 n이 작으면 같습니다
    4. 5.4 효율적인 정렬 알고리즘
      1. 5.4.1 정렬 알고리즘의 시간 비용
      2. 5.4.2 최악의 경우에 정렬 알고리즘 교체하기
      3. 5.4.3 입력 데이터의 특성 활용하기
    5. 5.5 최적화 패턴
      1. 5.5.1 사전 계산
      2. 5.5.2 지연 계산
      3. 5.5.3 배칭
      4. 5.5.4 캐싱
      5. 5.5.5 특수화
      6. 5.5.6 더 큰 조각 선택하기
      7. 5.5.7 힌팅
      8. 5.5.8 예상 경로 최적화
      9. 5.5.9 해싱
      10. 5.5.10 이중 검사
    6. 5.6 마치며
  7. Chapter 6 동적 할당 변수 최적화
    1. 6.1 C++ 변수
      1. 6.1.1 변수의 저장 기간
      2. 6.1.2 변수의 소유권
      3. 6.1.3 값 객체와 엔티티 객체
    2. 6.2 C++ 동적 변수 API
      1. 6.2.1 스마트 포인터는 동적 변수의 소유권을 자동화합니다
      2. 6.2.2 동적 변수는 런타임 비용이 있습니다
    3. 6.3 동적 변수 사용 줄이기
      1. 6.3.1 클래스 인스턴스를 정적으로 만드세요
      2. 6.3.2 정적 자료구조를 사용하세요
      3. 6.3.3 new 대신 std::make_shared를 사용하세요
      4. 6.3.4 소유권을 불필요하게 공유하지 마세요
      5. 6.3.5 동적 변수를 소유하기 위한 ‘소유 포인터’를 사용하세요
    4. 6.4 동적 변수의 재할당 줄이기
      1. 6.4.1 동적 변수를 미리 할당해 재할당을 방지하세요
      2. 6.4.2 반복문 바깥에서 동적 변수를 만드세요
    5. 6.5 불필요한 복사 제거하기
      1. 6.5.1 클래스 정의에서 원치 않는 복사 방지하기
      2. 6.5.2 함수 호출에서 복사 제거하기
      3. 6.5.3 함수 반환에서 복사 제거하기
      4. 6.5.4 복사 없는 라이브러리
      5. 6.5.5 COW 구현하기
      6. 6.5.6 슬라이스 자료구조
    6. 6.6 이동 문법 구현하기
      1. 6.6.1 표준이 아닌 복사 문법: 고통스러운 핵
      2. 6.6.2 std::swap(): 가난뱅이의 이동 문법
      3. 6.6.3 엔티티의 소유권 공유
      4. 6.6.4 이동 문법의 이동 부분
      5. 6.6.5 이동 문법을 사용하도록 코드 갱신하기
      6. 6.6.6 이동 문법의 미묘한 부분
    7. 6.7 평평한 자료구조
    8. 6.8 마치며
  8. Chapter 7 문장 최적화
    1. 7.1 반복문에서 코드 제거하기
      1. 7.1.1 반복문의 종룟값을 캐싱하세요
      2. 7.1.2 더 효율적인 반복문을 사용하세요
      3. 7.1.3 값을 증가하는 대신 감소하게 하세요
      4. 7.1.4 반복문에서 불변 코드를 제거하세요
      5. 7.1.5 반복문에서 불필요한 함수 호출을 제거하세요
      6. 7.1.6 반복문에서 숨겨진 함수 호출을 제거하세요
      7. 7.1.7 반복문에서 비용이 크고 변화가 느린 호출을 제거하세요
      8. 7.1.8 반복문을 함수 안에 넣어 호출 오버헤드를 줄이세요
      9. 7.1.9 어떤 행동을 하는 횟수를 줄이세요
      10. 7.1.10 그 밖에 다른 기법
    2. 7.2 함수에서 코드 제거하기
      1. 7.2.1 함수 호출 비용
      2. 7.2.2 간단한 함수는 인라인으로 선언하세요
      3. 7.2.3 함수를 처음 사용하기 전에 정의하세요
      4. 7.2.4 사용하지 않는 다형성을 제거하세요
      5. 7.2.5 사용하지 않는 인터페이스를 버리세요
      6. 7.2.6 템플릿으로 컴파일 타임에 구현을 선택하세요
      7. 7.2.7 PIMPL 관용구를 사용하는 코드를 제거하세요
      8. 7.2.8 DLL을 호출하는 코드를 제거하세요
      9. 7.2.9 멤버 함수 대신 정적 멤버 함수를 사용하세요
      10. 7.2.10 가상 소멸자를 기본 클래스로 옮기세요
    3. 7.3 표현식 최적화
      1. 7.3.1 표현식을 단순하게 만드세요
      2. 7.3.2 상수를 함께 모으세요
      3. 7.3.3 비용이 적은 연산자를 사용하세요
      4. 7.3.4 부동 소수점 연산 대신 정수 연산을 사용하세요
      5. 7.3.5 double이 float보다 빠를 수 있습니다
      6. 7.3.6 반복 계산을 닫힌 형태로 바꾸세요
    4. 7.4 제어 흐름 최적화
      1. 7.4.1 if-elseif-else 대신 switch를 사용하세요
      2. 7.4.2 switch나 if 대신 가상 함수를 사용하세요
      3. 7.4.3 비용이 들지 않는 예외 처리를 사용하세요
    5. 7.5 마치며
  9. Chapter 8 라이브러리 최적화
    1. 8.1 표준 라이브러리 최적화
      1. 8.1.1 C++ 표준 라이브러리의 철학
      2. 8.1.2 C++ 표준 라이브러리의 사용에 관한 사안
    2. 8.2 기존 라이브러리 최적화
      1. 8.2.1 가능한 한 적게 수정하세요
      2. 8.2.2 기능을 변경하기 보다는 추가하세요
    3. 8.3 최적화된 라이브러리 설계
      1. 8.3.1 서둘러 코딩하면 두고두고 후회합니다
      2. 8.3.2 절약은 라이브러리 설계의 덕목입니다
      3. 8.3.3 라이브러리 바깥에서 메모리 할당을 결정하세요
      4. 8.3.4 확신이 서지 않으면 속도를 위한 라이브러리 코드를 작성하세요
      5. 8.3.5 함수가 프레임워크보다 최적화하기 쉽습니다
      6. 8.3.6 상속 계층 구조를 평평하게 만드세요
      7. 8.3.7 호출 체인을 평평하게 만드세요
      8. 8.3.8 계층화된 설계를 평평하게 만드세요
      9. 8.3.9 동적 검색을 피하세요
      10. 8.3.10 ‘신의 함수’를 조심하세요
    4. 8.4 마치며
  10. Chapter 9 검색 및 정렬 최적화
    1. 9.1 std::map과 std::string을 사용한 키/값 테이블
    2. 9.2 검색 성능 향상을 위한 툴킷
      1. 9.2.1 측정 기준치를 만드세요
      2. 9.2.2 최적화할 코드를 확인하세요
      3. 9.2.3 최적화할 코드를 분해하세요
      4. 9.2.4 알고리즘과 자료구조를 변경하거나 바꾸세요
      5. 9.2.5 사용자 정의 추상화에 최적화 과정 사용하기
    3. 9.3 std::map을 사용한 검색 최적화
      1. 9.3.1 std::map에 고정된 크기를 갖는 문자열 키를 사용하세요
      2. 9.3.2 std::map에 C 스타일 문자열 키를 사용하세요
      3. 9.3.3 키가 값에 있을 때 맵의 사촌인 std::set을 사용하기
    4. 9.4 헤더를 사용한 검색 최적화
      1. 9.4.1 시퀀스 컨테이너의 검색을 위한 키/값 테이블
      2. 9.4.2 이름이 명확하고 시간 비용이 O(n)인 std::find()
      3. 9.4.3 값을 반환하지 않는 std::binary_search()
      4. 9.4.4 std::equal_range()를 사용한 이진 검색
      5. 9.4.5 std::lower_bound()를 사용한 이진 검색
      6. 9.4.6 직접 코딩한 이진 검색
      7. 9.4.7 strcmp()를 사용해 직접 코딩한 이진 검색
    5. 9.5 해시 키/값 테이블 검색 최적화
      1. 9.5.1 std::unordered_map으로 해싱하기
      2. 9.5.2 고정된 크기를 갖는 문자 배열 키로 해싱하기
      3. 9.5.3 NULL로 끝나는 문자열 키로 해싱하기
      4. 9.5.4 사용자 정의 해시 테이블로 해싱하기
    6. 9.6 스테파노프의 추상화 패널티
    7. 9.7 C++ 표준 라이브러리로 정렬 최적화
    8. 9.8 마치며
  11. Chapter 10 자료구조 최적화
    1. 10.1 표준 라이브러리 컨테이너 알아보기
      1. 10.1.1 시퀀스 컨테이너
      2. 10.1.2 연관 컨테이너
      3. 10.1.3 표준 라이브러리 컨테이너로 실험하기 (1/2)
      4. 10.1.3 표준 라이브러리 컨테이너로 실험하기 (2/2)
    2. 10.2 std::vector와 std::string
      1. 10.2.1 재할당의 성능 결과
      2. 10.2.2 std::vector에서 삽입/삭제하기
      3. 10.2.3 std::vector에서 코드 반복 실행하기
      4. 10.2.4 std::vector 정렬하기
      5. 10.2.5 std::vector에서 검색하기
    3. 10.3 std::deque
      1. 10.3.1 std::deque에서 삽입/삭제하기
      2. 10.3.2 std::deque를 사용하는 반복문
      3. 10.3.3 std::deque 정렬하기
      4. 10.3.4 std::deque에서 검색하기
    4. 10.4 std::list
      1. 10.4.1 std::list에서 삽입/삭제하기
      2. 10.4.2 std::list에서 반복하기
      3. 10.4.3 std::list 정렬하기
      4. 10.4.4 std::list에서 검색하기
    5. 10.5 std::forward_list
      1. 10.5.1 std::forward_list에서 삽입/삭제하기
      2. 10.5.2 std::forward_list에서 반복하기
      3. 10.5.3 std::forward_list 정렬하기
      4. 10.5.4 std::forward_list에서 검색하기
    6. 10.6 std::map과 std::multimap
      1. 10.6.1 std::map에서 삽입/삭제하기
      2. 10.6.2 std::map를 사용한 반복문
      3. 10.6.3 std::map 정렬하기
      4. 10.6.4 std::map에서 검색하기
    7. 10.7 std::set과 std::multiset
    8. 10.8 std::unordered_map과 std::unordered_multimap
      1. 10.8.1 std::unordered_map에서 삽입/삭제하기
      2. 10.8.2 std::unordered_map에서 반복하기
      3. 10.8.3 std::unordered_map에서 검색하기
    9. 10.9 다른 자료구조
    10. 10.10 마치며
  12. Chapter 11 입출력 최적화
    1. 11.1 파일을 읽는 방법
      1. 11.1.1 저렴한 함수 시그니처 만들기
      2. 11.1.2 호출 체인 짧게 만들기
      3. 11.1.3 재할당 줄이기
      4. 11.1.4 더 큰 입력 버퍼 사용하기
      5. 11.1.5 한 번에 한 줄씩 읽기
      6. 11.1.6 다시 호출 체인 짧게 만들기
      7. 11.1.7 도움이 되지 않는 것들
    2. 11.2 파일 쓰기
    3. 11.3 std::cin으로 읽어서 std::cout으로 쓰기
    4. 11.4 마치며
  13. Chapter 12 동시성 최적화
    1. 12.1 동시성
      1. 12.1.1 동시성 용어 살펴보기
      2. 12.1.2 교차 실행
      3. 12.1.3 순차적 일관성
      4. 12.1.4 경쟁 상태
      5. 12.1.5 동기화
      6. 12.1.6 원자성
    2. 12.2 C++ 동시성 기능
      1. 12.2.1 스레드
      2. 12.2.2 프로미스와 퓨처
      3. 12.2.3 비동기 태스크
      4. 12.2.4 뮤텍스
      5. 12.2.5 락
      6. 12.2.6 조건 변수
      7. 12.2.7 공유 변수에 대한 원자적 연산
      8. 12.2.8 미래의 C++ 동시성 기능
    3. 12.3 C++ 프로그램 스레드 최적화
      1. 12.3.1 std::thread보다는 std::async를 사용하세요
      2. 12.3.2 실행 가능한 스레드를 코어 수만큼 많이 만드세요
      3. 12.3.3 태스크 큐와 스레드 풀 구현하기
      4. 12.3.4 별도의 스레드에서 I/O 수행하기
      5. 12.3.5 동기화 없는 프로그램
      6. 12.3.6 시작 및 종료 코드 제거하기
    4. 12.4 더 효율적인 동기화 만들기
      1. 12.4.1 임계 구역의 범위 줄이기
      2. 12.4.2 동시 스레드 수 제한하기
      3. 12.4.3 놀란 양 떼 피하기
      4. 12.4.4 락 전달 피하기
      5. 12.4.5 경쟁 상태 줄이기
      6. 12.4.6 싱글 코어 시스템에서 바쁜 대기를 하지 마세요
      7. 12.4.7 영원히 대기하지 마세요
      8. 12.4.8 사용자 정의 뮤텍스 사용은 효과적이지 않을 수 있습니다
      9. 12.4.9 생산자 출력 큐의 길이 제한하기
    5. 12.5 동시성 라이브러리
    6. 12.6 마치며
  14. Chapter 13 메모리 관리 최적화
    1. 13.1 C++ 메모리 관리 API
      1. 13.1.1 동적 변수의 생명 주기
      2. 13.1.2 메모리를 할당하고 해제하는 메모리 관리 함수
      3. 13.1.3 new 표현식은 동적 변수를 생성합니다
      4. 13.1.4 delete 표현식은 동적 변수를 없앱니다
      5. 13.1.5 소멸자를 명시적으로 호출하면 동적 변수를 파괴합니다
    2. 13.2 고성능 메모리 관리자
    3. 13.3 클래스 한정 메모리 관리자 제공하기
      1. 13.3.1 고정된 크기의 블록을 갖는 메모리 관리자
      2. 13.3.2 블록 아레나
      3. 13.3.3 클래스 한정 operator new() 추가하기
      4. 13.3.4 고정된 크기의 블록을 갖는 메모리 관리자의 성능
      5. 13.3.5 고정된 크기의 블록을 갖는 메모리 관리자의 변형
      6. 13.3.6 스레드 세이프하지 않은 메모리 관리자는 효율적입니다
    4. 13.4 사용자 정의 표준 라이브러리 할당자 제공하기
      1. 13.4.1 미니멀한 C++11 할당자
      2. 13.4.2 C++98 할당자의 추가 정의 (1/2)
      3. 13.4.2 C++98 할당자의 추가 정의 (2/2)
      4. 13.4.3 고정된 크기의 블록을 갖는 할당자
      5. 13.4.4 문자열에 대한 고정된 크기의 블록을 갖는 할당자
    5. 13.5 마치며
  15. index (1/2)
  16. index (2/2)

Product information

  • Title: C++ 최적화: 최고 성능을 구현하는 10가지 검증된 기법
  • Author(s): 옥찬호, 커트 건서로스
  • Release date: August 2019
  • Publisher(s): Hanbit Media, Inc.
  • ISBN: 9791162241981