inline 함수는 C++의 실행 속도 개선을 위해 등장 했습니다.
C++에서는 기본적으로 클래스 선언을 통한 맴버함수가 많이 이용되는데, 이러한 경우 보통
간단한 기능을 하는 함수들이 많이 만들어지게 됩니다.
생성자, getter(), setter(), print() 등 과같은 간단한 함수들 말이죠.
함수들이 간결하여 실행속도에 영향을 끼지지 않을 것 같지만 함수 호출 과정에서 프로그램 속도가 떨어지게 됩니다.
함수의 호출은 다음과 같이 진행됩니다.
※찾아보니 중간에 레지스터에도 값이 저장되는데 어떤 값이 무슨 이유로 저장되는지는 저도 잘 몰라서 일단 제외했습니다.
코드로 보면 다음과 같습니다.
#include<iostream>
int fnc_1(int a, int b){ //매개변수 스택에 저장
return a + b; //리턴 값을 임시 저장소에 저장.
}
int main(void){
int num;
num = fnc_1(5,1); //함수 호출 시점, 이곳의 주소값을 스택에 저장
return 0;
}
이러한 것들이 수십, 수백, 수천번 반복되게 되면 불필요한 작업으로 이어지게 됩니다.
처리시간, 메모리, cpu자원이 불필요하게 쓰이게 되죠.
이것을 가르켜 오버헤드(overhead) 현상이라고 합니다.
특히 C언어 보단 C++에서 이 현상이 많이 자주 일어나 이를 개선하기 위해서 inline함수라는 것이 생겼습니다.
inline함수의 매커니즘을 알기 전에 컴파일 과정에 대한 이해가 필요합니다.
컴파일이란?
쉽게 말해 사람이 보기 편하게 작성된 실행 코드들을(C, C++, JAVA, Python 등...) 컴퓨터가 보기 편하게 기계어로 변환해 주는 작업을 말합니다.
때문에 컴파일이 완료되면 .obj파일이 생성이 됩니다.
컴파일은 프로그램의 실행이 아니라 말그대로 기계어로 번역의 의미를 지니며 함수에 대한 실행은 여기선 이뤄지지 않습니다.
때문에 해더파일에 선언된 함수들. 즉, 실행코드에 사용될 라이브러리(함수들)를 연결시켜 주는 과정이 링크 입니다.
inline함수는 이 컴파일 과정에서 처리가 진행 됩니다.
inline함수의 선언 방법은 다음과 같습니다.
#include<iostream>
inline int fnc_1(int a, int b){
return a + b;
}
int main(void){
int num;
num = fnc_1(5, 1);
return 0;
}
해당 함수 앞에 'inline'이라는 키워드를 선언만 해주면 됩니다.
이렇게 선언되면 프로그램 실행시 다음과 같이 동작하게 됩니다.
#include<iostream>
inline int fnc_1(int a, int b){
return a + b;
}
int main(void){
int num;
//num = fnc_1(5, 1);
num = 5 + 1; //이렇게 변환되어 컴파일이 됩니다.
return 0;
}
※주의해야 할 점은 실제로 사람이 작성한 코드가 이렇게 변환되는 것이 아닙니다.!!
컴파일 과정에서 변환 되는 것으로 obj파일이 생성되는 과정에서 위와 같은 형태로 변하게 됩니다.
따라서 실행 코드를 뜯어 봤을때(어셈블리어를 봤을 때) 과정을 보면
함수 호출 과정은 사라지고 함수에 있는 몸통부분만 실행되는 것을 확인할 수 있습니다.
일반적인 함수 호출 예시
inline후 호출된 함수
※위 어셈블리어 예시는 이해를 돕기위해 제가 가저온 이미지 입니다.
처리되는 과정을 보면 inline함수 부분은 함수 호출부분이 없이 바로 덧셈이 계산되는 걸 알 수 있습니다.
이런점 때문에 inline함수를 사용하게 되면 실행속도가 굉장히 빨라집니다.
즉, 코드의 최적화가 이뤄진다고 말할 수 있겠습니다.
하지만 무조건 inline함수가 좋은건 아닙니다.
inlne함수가 많아지면 실행코드가 늘어나가되어
결국.... 컴파일 시간이 늘어나고 실행파일의 크기가 커지게 됩니다.
이 무슨말이냐???!!!
다음 예시를 보겠습니다.
#include<iostream>
int fnc_1(int a, int b){
int num;
if(a < b)
num = a + b;
else
num = a - b;
if(num > 0){
for(int i = 0; i < num; i++)
num += i;
}
return num;
}
int main(void){
int num1, num2, num3;
num1 = fnc_1(5, 1);
num2 = fnc_1(1, 2);
num3 = fnc_1(100, 200);
return 0;
}
위와 같은 코드가 있다고 가정해 보겠습니다.(아무의미 없는 계산식 코드 입니다.)
저 함수를 inline화 시키게 된다면???
main함수의 fnc_1() 호출 부분은 fnc_1()함수의 몸통부분으로 변환되어 들어가게 될 것입니다.
그렇게 된다면 코드의 길이가 함수 몸통 부분만큼 늘어나겠죠??
그리고 fnc_1()함수를 3번 호출하니 3개 몸통 부분만큼 늘어나겠죠???
그렇게 된다면 실행속도는 빨라지지만 실행파일의 크기는 늘어나게 되버립니다.
이를 방지하기 위해 컴파일러는 inline함수들을 직접 선언하여 컴파일 하기도 하며
inline함수로 선언된 부분을 일반 함수로 처리하기도 합니다.
(굉장히 똑똑하죠.....)
정리해보겠습니다.
inline함수의 장점
1. 실행속도가 빨라진다.(즉, 코드가 최적화 된다.)
inline 함수의 단점
1. 불필요하게 사용시 컴파일 속도가 느려진다.
2. 실행파일의 크기가 커지게 된다.
'프로그래밍 > C++' 카테고리의 다른 글
C++ 함수 포인터란? 왜 사용할까? (2) | 2019.07.20 |
---|---|
c++ 함수 객채란?? (0) | 2019.07.18 |
C++ Lambda 사용 이유와 사용 방법 (12) | 2019.07.01 |
C++ 변수 형 타입 auto (0) | 2019.07.01 |
C++ 템플릿 클래스 (0) | 2019.05.17 |
댓글