728x90
오늘은 RVO 랑 NRVO 에 대해서 알아보도록 하겠습니다.
1. 개요
RVO 랑 NRVO는 함수에서 C++ 객체지향을 어떻게 하면 빠른 속도와 컴파일러단에서 부터 코드를 최적화 시켜서 더욱 빠르고 정확하게 실행 할 수 있는지에 대한 내용입니다.
대표정으로 RVO 와 NRVO 가 있습니다.
RVO = Return Value Optimization
NRVO = Named Return Value Optimization
2. RVO VS NRVO
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class A
{
private:
string s;
public:
A(string s) : s(s)
{
cout <<s<< " 초기 생성자" << endl;
}
A(const A& a)
{
this->s = a.s;
cout <<s<< " 복사 생성자" << endl;
}
A(const A&& a)
{
this->s = a.s;
cout <<s<< " 이동 생성자" << endl;
}
~A()
{
cout <<s<< "소멸자" << endl;
}
};
/**NRVO*/
A makeA(string name)
{
A a(name);
return a;
}
/**RVO*/
A makeA2(string name)
{
return A(name);
}
int main()
{
A a1 = makeA("a1");
A a2 = makeA2("a2");
return 0;
}
이러한 형태를 가지고 있습니다. 이런경우 어떻게 호출순서가 되면
- A a1 에서 makeA 함수를 R-Value 형태로 return 값을 받기위해 함수진입
- makeA에서 파라미터로 받은 name을 A a(name) 객체를 생성후 생성자호출
- return a 를통해 객체에 이동생성자를 불러 임시 객체를 만들고 소멸자를 콜
- a1에 할당
- a2는 makeA2 함수를 R-Value 형태로 return 값을 받기위해 함수진입
- 들어가는 동시에 return을 통해 생성자만 호출 후 반환
- a2에 할당
이를 통해 RVO 가 NRVO보다 좀더 속도가 빠르고 굳이 임시객체에 할당을 할 필요가 없다는 사실을 알았습니다.
하지만 이 모드는 Visual Studio에서 Debug모드로 실행했을때에 결과이며
Release 모드로 실행하면 다음과 같은 현상이 발생합니다.
이게 무슨일인가여??
사실 Release 모드는 Visual Studio에서 컴파일러 상에서 스스로 최적화를 위해 RVO로 변환하여 컴파일을 하기 때문입니다.
A = 다음의 우측값으로 넣을 필요 없이 바로 A에 대입하면 된다는것을 컴파일러가 인지하고 최적화를 하기 때문입니다.
3. 요약
- 최적화를 위해 RVO를 사용하는것이 좋다 NRVO는 괜히 임시 객체를 만들어 시간이 더 소모된다.
- 하지만 Visual Studio에서는 자체적으로 최적화를 시키는 Release 모드가 있다.
- 왜냐하면 Release모드는 최종 배포하는 모드이기 떄문에 컴파일러가 더욱 신경을 써주는거 같다.
'개발자 면접 공부 > C-C++' 카테고리의 다른 글
정렬 알고리즘 (버블, 삽입, 선택) (0) | 2023.05.13 |
---|---|
virtual 생성자와 생성자 안에 virtual 함수 부르는 설명 (2) | 2023.05.12 |
Constexpr VS Const (0) | 2023.05.09 |
const int* p 와 int * const p의 차이점 (2) | 2023.05.07 |
C++ 템플릿(함수 템플릿) (0) | 2022.09.22 |