2017년 6월 28일 수요일

[Effective C++] 항목 30 : 인라인 함수는 미주알고주알 따져서 이해해 두자.

인라인 함수를 사용하면 컴파일러가 함수 본문에 대해 문맥별 최적화를 걸기가 용이해집니다.
인라인 함수의 아이디어는 함수 호출문을 그 함수의 본문으로 바꿔치기하자는 것 남발했다가는 코드의 크기가 커질 게 뻔하다.

인라인 함수로 부풀려진 코드는 성능의 걸림돌이 되기 쉽다. 페이징 횟수가 늘어나고, 명령어 캐시 적중률이 떨어질 가능성도 높아진다.

본문 길이가 굉장이 짧은 인라인 함수를 사용하면, 함수 본문에 대해 만들어지는 코드의 크기가 함수 호출분에 대해 만들어지는 코드보다 작아질 수도 있다.(목적 코드의 크기도 작아지며 명령어 캐시 적중률도 높아진다.

inline은 컴파일러에 대해 '요청'하는 것이지, '명령'이 아니다.

클래스 정의 안에 함수를 정의해 넣으면 컴파일러는 그 함수를 인라인 함수 후보로 찍습니다.
(암시적 정의)

함수 앞에 inline을 붙이면 명시적 정의

inline은 컴파일러 선에서 무시할 수 있는 요청이다.
아무리 인라인 함수로 선언되어 있어도 자신이 보기에 복잡한 함수는 절대로 인라인 확장의 대상에 넣지 않는다.
가상함수 호출 같은 것은 절대로 인라인 해주지 않는다.

보기에 확실한 인라인 함수도 '어떻게 호출하느냐'에 따라 인라인이 되기도 하고 안 되기도 한다는 이야기.

inline void f() {...}; // 컴파일러가 반드시 인라인 해주는 함수라고 가정하고

void (*pf)() = f; // pf는 f를 가리키는 함수 포인터.

f(); // 이 호출은 인라인 될 것이다. 평범한 함수 호출이므로

pf(); // 이 호출은 인라인 되지 않는다 함수 포인터를 통해 호출하고 있으므로

어떤 배열의 원소가 객체일 경우가 대표적인 예인데, 배열을 구성하는 객체들을 생성하고 소멸시킬 때 생성자/소멸자의 함수 포인터를 얻어내려면 함수 본문이 반드시 필요합니다.

생성자와 소멸자는 인라인하기에 그리 좋지 않은 함수입니다.

대부분의 디버거가 무척이나 곤란해 하는 비호감 대상이 바로 인라인 함수라는 점

* 함수 인라인은 작고, 자주 호출되는 함수에 대해서만 하는 것으로 묶어둡시다.
이렇게 하면 디버깅 및 라이브러리의 바이너리 업그레이드가 용이해지고, 자칫 생길 수 있는 코드 부풀림 현상이 최소화되며, 프로그램의 속력이 더 빨라질 수 있는 여지가 최고로 많아집니다.

* 함수 템플릿이 대개 헤더 파일에 들어간다는 일반적인 부분만 생각해서 이들을 inline으로 선언하면 안됩니다.


출처: http://kihyun3297.tistory.com/32 [시작해봅니다.]

댓글 없음:

댓글 쓰기

[Effective C++] 항목 30 : 인라인 함수는 미주알고주알 따져서 이해해 두자.

인라인 함수를 사용하면 컴파일러가 함수 본문에 대해 문맥별 최적화를 걸기가 용이해집니다. 인라인 함수의 아이디어는  함수 호출문을 그 함수의 본문으로 바꿔치기하자는 것  남발했다가는 코드의 크기가 커질 게 뻔하다. 인라인 함수로 부풀려진 ...