0. 정리

  • 최적화는 다른 코딩 작업보다 과학적 사고방식을 더 많이 요구하는 실험과학이다. 성공을 위해선 행동을 관찰하고, 관찰을 기반으로 가설을 세우고, 가설을 지지하거나 반박하는 실험을 수행하는 과정을 반복해야 한다.

  • 최적화를 위한 실험은 종종 직관과 상충하는 결과를 보여준다.

  • 숙련된 개발자들로 이루어진 팀에서 작성한 코드에서조차 최적화의 여지는 많을 수 있다.

  • 최적화가 꼭 개발 효율을 낮추는 것은 아니다.

  • C++ 최적화를 위한 방법은 다음이 있을 수 있다.

    • 더 좋은 컴파일러를 사용하기

      C++ 컴파일러들은 동일한 C++코드에 대해 각자 조금씩 다른 결과를 생성한다. 이를테면, GCC는 느리지만 표준을 잘 준수하는 바이트코드를 만들어 내며, MSVC는 이보다는 더 빠르지만 조금 덜 표준을 준수하는 식이다.

    • 더 좋은 알고리즘을 사용하기

      최적화의 시작은 최적의 알고리즘 선택에서 비롯된다. 덜 좋은 알고리즘을 최적화하는 것보다 더 좋은 알고리즘을 채택하는 것이 더 나은 결과를 보여준다. 데이터를 정렬하기 위해 삽입 정렬을 사용하는 것보다 병합 정렬을 사용하는 것이 훨씬 나은 결과를 보여주며, 이는 데이터가 많아질수록 더욱 유효하다.

    • 더 좋은 라이브러리 사용하기

      C++ 컴파일러와 함께 제공되는 C++ 탬플릿 및 런타임 라이브러리는 의외로 실행 속도를 크게 신경쓰지 않았다. 이들은 유지보수성과 범용성, 견고성을 가장 중요한 목표로 개발된 라이브러리이기 때문이다. 따라서 때로는 STL보다 Boost, Google, 혹은 오픈 소스 라이브러리들이 더 나은 속도를 보이는 경향이 있으며, 심지어는 속도 우위를 위해 표준 라이브러리의 안정성과 견고성을 포기하고 해당 프로젝트만을 위한 자체 라이브러리를 구성하는 방법도 있다.

    • 메모리 할당과 복사 줄이기

      메모리 관리자를 호출하는 횟수를 줄이는 방법을 알고 있다는 것은 그 자체만으로도 다른 방법들 없이 성공적인 최적화를 할 수 있을 정도로 중요하고 효과적이다. C++의 대부분의 언어 기능은 길어야 명령어 몇 줄 만에 처리되는 빠른 실행 속도를 보이지만, 메모리 관리자 호출 비용은 명령어 몇천 줄에 달한다.

    • 자주 실행되는 계산 제거하기

      메모리 할당이나 함수 호출등을 제외하면 단일 C++문의 비용은 일반적으로 매우 적다. 그러나 이러한 명령이라 할지라도 루프나 이벤트 처리 코드에 포함되어 동일한 코드를 수백만 번 수행하게 된다면 얘기가 달라진다. 따라서 루프나 이벤트 처리같은 반복적으로 발생하는 구문 블럭에선 최대한 불필요한 계산을 제거해야 하며, 이를 위해서 자주 실행되는 코드를 찾는 방법을 견지할 필요가 있다.

    • 더 좋은 자료구조 사용하기

      각 자료구조마다 동일한 데이터를 저장한다 하더라도 서로 다른 특성을 지닐 수 있다. 배열은 O(1)의 조회 속도를 가지지만 삽입/삭제가 느리며, 리스트는 그 반대인 것을 예로 들 수 있다. 이 말은 다양한 알고리즘이 자료구조에 의존적이라는 의미이기도 하다. 또한 각 자료구조는 서로 다른 방법으로 메모리 관리자를 사용하며, 자료구조에 따라 캐시 히트율이 달라진다.

    • 동시성 증가시키기

      여러 프로세서 코어가 존재하는 시스템에서, 동시 스레드를 사용할 경우 이들을 사용하는 방법에 따라 천차만별의 결과와 속도가 나올 수 있다. 따라서 최적화를 위해선 최대한 스레드 간의 동시성을 증가시키는 방법을 채택해야 하며, 이를 위한 방법을 알아야 한다.

    • 메모리 관리자 최적화하기

      C++ 런타임 라이브러리의 일부인 메모리 관리자는 동적 메모리 할당을 관리하며 많은 C++프로그램에서 자주 실행되는 코드이다. C++에는 메모리 관리를 위한 수많은 API가 존재하며, 메모리 관리의 방식을 개발자가 지정할 수도 있다는 점을 염두에 두어야 한다.