Table of Contents 어떻게 선을 그을까? 그리고 언제 그을까? 입력과 출력은? 플러그인 아키텍처 플러그인에 대한 논의 결론 소프트웨어 아키텍처는 선을 긋는 기술이며, 이 선을 경계(boundary)라고 부른다. 경계는 소프트웨어 요소를 서로 분리하고, 경계 한편에 있는 요소가 반대편에 있는 요소를 알지 못하도록 막...
Boost.Preprocessor Library
코드를 읽다가 Boost에서 제공하는 Preprocessor 라이브러리가 있다는 사실을 알게 되었다. Preprocessor 라이브러리를 사용하여 함수의 원형을 작성 하고 여러개의 함수 인자를 받을 수 있도록 전처리기가 함수를 생성하여 오버로딩을 하는 코드였다. 일단, Preprocessor 라이브러리의 메크로로 생성한 코드는 컴파일 전처리 단계에서 ...
Overloading Typecasts
C++은 기본 타입에 대한 형 변환을 어떻게 수행할지 알고 있다. 하지만 사용자 정의 클래스는 어떻게 형 변환을 수행할지 알지 못 한다. 아래의 클래스를 살펴보자. class Cent { private: int m_cents; public: Cent(int cents = 0) : m_cents(cents) {} int get_...
EFFICIENT C++_단일 쓰레드 메모리 풀링
메모리를 자주 할당하고 해지하는 것은 응용프로그램 성능을 저하시키는 주요한 요소이다. 성능 저하는 기본 메모리 관리자가 일반적인 목적을 가지고 있기 때문에 발생한다. 특화된 메모리 관리자를 개발하여 이러한 사항을 극복할 수 있다. 이러한 메모리 관리자를 개발하고자 할때, 메모리의 크기와 동시성이라는 문제를 생각해야 한다. 메모리 크기는 다음 2가지를 ...
EFFICIENT C++_임시 객체
임시 객체 생성은 성능적으로 작은 영향을 주는 부분은 아니다. 즉, 임시 객체의 기원, 그것의 비용 그리고 임시 객체를 제거할 수 있는 방법을 알지 않고서는 효율적인 코드를 작성하기 힘들다. 임시 객체는 소스 코드에 존재하지 않고 컴파일러가 조용히 객체를 만들어 낸다. 컴파일러가 어떤 코드에서 임시 객체를 만들어 내는지 찾아내려면 숙련된 관찰력이 필...
EFFICIENT C++_반환값 최적화
앞에서 불필요한 객체의 생성과 소멸을 제거할 때 마다 성능이 좋아지는 것을 보았다. 이번에는 속도를 위해서 컴파일러가 수행하는 Return Value Optimization을 살펴 보겠다. 값으로 반환의 동작 원리 아래는 Complex 클래스로 복소수를 표현하고 있다. class Complex { friend Complex operator+(...
EFFICIENT C++_가상 함수
동적 바인딩 덕분에 프로그래머는 형식 확인을 컴파일러에게 맡기게 되었고 많이 편해졌다. 반대로 동적 바인딩은 성능에 부정적인 영향을 끼칠 수 있다. 가상 함수 기법 만약 가상 함수를 사용하고 싶지 않다면, 직접 형식 확인 코드를 작성하여 동적 바인딩을 흉내를 낼수있다. 다음은 동물원 동물을 클래스로 표현한 것이다. class ZooAnimal {...
EFFICIENT C++_생성자와 소멸자
상속 이상적으로는 생성자와 소멸자는 오버헤드를 가지지 않아야 한다. 생성자와 소멸자는 오직 필수적인 초기화와 정리 작업을 수행하며, 일반적인 컴파일러는 이것들을 인라인 함수로 만들것이다. 하지만, 상속과 합성 구현은 가끔 혹은 절대 사용되지 않는 연산을 수행하기도 한다. 상속과 합성 구현은 코드의 재사용을 위한 기술이다. 즉, 코드의 재사용과 성능과...
Efficient C++_로깅과 관련된 성능 이야기
소프트웨어를 유지보수를 하다보면 로깅이 매우 중요하다. 로깅을 통해서 문제 상황 추적 및 프로그램의 실행 흐름을 파악하는데 많은 도움이 된다. 이런 로깅과 관련된 코드는 성능과 관련된 여러가지 문제들을 만나기 쉽다. 로깅과 관련된 성능 최적화의 극단적인 방법은 추적 호출을 #ifdef 블록 안에 내장하여 성능 부하를 제거하는 것이다. #ifdef ...
Functors: Function Objects in C++
C와 C++ 모두 function pointer를 지원한다. function pointer는 특정 명령을 수행하는 함수를 전달할 수 있는 방법 중 하나이다. 하지만, function pointer는 매우 제한적인데, function pointer는 컴파일 시점에 해당 함수가 정의되어 있어야 한다. 그럼 왜 이것 때문에 function pointer가...