소년코딩

인라인 함수 (inline function)

함수를 사용하면 다음과 같은 많은 이점을 얻을 수 있다.

  • 함수 내부의 코드를 재사용할 수 있다.
  • 인스턴트 코드보다 함수에서 코드를 변경하거나 업데이트하기가 더 쉽다.
  • 함수 이름을 통해 코드가 무엇을 의미하는지 이해하기 더 쉽다.
  • 함수는 함수 호출 인수가 함수 매개 변수와 일치하는지 확인하기 위해 타입 검사를 한다. (매크로는 안한다.)
  • 함수는 프로그램을 디버그하기 쉽게 만든다.

그러나 함수는 함수가 호출될 때마다 발생하는 일정량의 성능 오버헤드가 있다는 단점이 있다. 이는 CPU가 다른 레지스터와 함께 실행 중인 현재 명령어의 주소를 저장해야 하므로(나중에 반환할 위치를 알 수 있도록) 모든 함수 매개 변수를 생성해야 한다. 할당된 값을 사용하면 프로그램이 새 위치로 분기된다. 내부에서 작성된 코드(인스턴트 코드)가 훨씬 더 빠르다.

크거나 복잡한 태스크를 수행하는 함수의 경우 함수 호출의 오버헤드는 함수가 실행되는 데 걸리는 시간과 비교할 때 중요하지 않다. 그러나 일반적으로 사용하는 작은 함수의 경우, 함수 호출에 필요한 시간이 실제로 함수 코드를 실행하는 데 필요한 시간보다 훨씬 많은 경우가 있다. 이로 인해 상당한 성능 저하가 발생할 수 있다.

C++은 인라인 함수(inline function)라는 내부에서 작성된 코드의 속도와 함수의 장점을 결합하는 방법을 제공한다. inline 키워드는 컴파일러에서 함수를 인라인 함수로 처리하도록 요청한다. 컴파일러가 코드를 컴파일하면 모든 인라인 함수가 인-플레이스(in-place) 확장된다. 즉, 함수 호출이 함수 자체의 내용 복사본으로 대체되어 함수 오버헤드가 제거된다! 단점은 인라인 함수가 모든 함수 호출에 대해 적절한 위치에서 확장되므로 인라인 함수가 길거나 인라인 함수를 여러 번 호출하는 경우 컴파일된 코드를 약간 더 크게 만들 수 있다는 것이다.

int min(int x, int y)
{
    return x > y ? y : x;
}

int main()
{
    std::cout << min(5, 6) << '\n';
    std::cout << min(3, 2) << '\n';
    return 0;
}

위 프로그램은 함수 min()을 두 번 호출하여 함수 호출 오버헤드 패널티를 두 번 발생시킨다. min() 함수는 짦은 함수이므로 인라인화 하기 좋다.

inline int min(int x, int y)
{
    return x > y ? y : x;
}

이제 프로그램이 main()을 컴파일하면 main() 다음과 같이 작성된 것처럼 기계 코드를 생성한다.

int main()
{
    std::cout << (5 > 6 ? 6 : 5) << '\n';
    std::cout << (3 > 2 ? 2 : 3) << '\n';
    return 0;
}

결론적으로 더 빠르게 실행된다.

코드를 부풀릴 가능성이 있으므로 함수를 인라인화 하는 것은 내부 루프가 없는 짧은 함수에 가장 적합하다. 또한 inline 키워드는 권장 사항일 뿐이다. 컴파일러는 인라인에 대한 요청을 자유롭게 무시할 수 있다. (긴 함수를 인라인화 하려고 하면 무시할 가능성이 있다.)

마지막으로, 현대 컴파일러는 자동으로 함수를 인라인화 하는 데 매우 뛰어나다. 함수를 인라인으로 표시하지 않더라도 컴파일러는 성능이 향상될 것으로 생각하는 함수를 인라인화 한다. 따라서 대부분의 경우 inline 키워드를 사용할 필요가 없다.

Rule: 인라인 함수를 알고 있어야 하지만 최신 컴파일러는 함수를 적절하게 인라인화 하므로 inline 키워드를 사용할 필요가 없다.


cpp 번역: 이 포스트의 원문은 http://www.learncpp.com/cpp-tutorial/75-inline-functions/ 입니다.

댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기