검색결과 리스트
NRVO에 해당되는 글 1건
- 2012.10.24 [ VC11-C++11 ] NRVO와 move 생성자에 의한 최적화
아래 코드에서 TEST1은 몇 번 생성될까요?
TEST1 GetTest1_1()
{
TEST1 test1;
test1.nValue = 11;
return test1;
}
int main()
{
....
auto test1_1 = GetTest1_1();
....
}
위의 코드를 실행하면 main에서 TEST1 객체 생성(1), GetTest1_1() 함수에서 TEST1 객체 생성(2)에 의해 TEST1은 총 2번 만들어집니다.
그러나 실제로는 C++ 최적화(즉 릴리즈모드로 컴파일 하면)에 의해 TEST1 객체는 한번만 생성합니다. 위의 최적화를 NRVO라고 합니다(RVO도 있습니다).
그런데 NRVO는 한계가 있습니다. 아래와 같은 경우에서는 NRVO 최적화를 사용할 수 없습니다.
TEST1 GetTest1_2( int nTemp )
{
TEST1 test1;
test1.nValue = 11;
if( nTemp > 100 )
{
test1.nValue = 111;
return test1;
}
return test1;
}
코드를 보면 알겠지만 TEST1 객체를 조건문에 의해서 다르게 반환하는 경우 컴파일러는 NRVO 최적화를 하지 않습니다.
이때는 C++11의 move 생성자를 사용하여 최적화를 할 수 있습니다.
C++11에서는 GetTest1_2와 같은 상황일 때 TEST1에 move 생성자를 정의해 놓으면 컴파일러가 move 생성자를 사용합니다.
당연하겠지만 move 생성자를 정의하고 있어도 NRVO를 사용할 수 있으면 NRVO 최적화를 최우선적으로 사용합니다.
< 예제 코드 >
#include <iostream>
struct TEST1
{
int nValue;
TEST1()
{
std::cout << "TEST1 생성자" << std::endl;
}
~TEST1()
{
std::cout << "TEST1 소멸자" << std::endl;
}
TEST1(const TEST1& obj)
{
nValue = obj.nValue;
std::cout << "TEST1 복사 생성자" << std::endl;
}
};
struct TEST2
{
int nValue;
TEST2()
{
std::cout << "TEST2 생성자" << std::endl;
}
~TEST2()
{
std::cout << "TEST2 소멸자" << std::endl;
}
TEST2(const TEST2& obj)
{
nValue = obj.nValue;
std::cout << "TEST2 복사 생성자" << std::endl;
}
TEST2(TEST2&& obj)
{
nValue = obj.nValue;
std::cout << "TEST2 move 생성자" << std::endl;
}
};
TEST1 GetTest1_1()
{
TEST1 test1;
test1.nValue = 11;
return test1;
}
TEST1 GetTest1_2( int nTemp )
{
TEST1 test1;
test1.nValue = 11;
if( nTemp > 100 )
{
test1.nValue = 111;
return test1;
}
return test1;
}
TEST2 GetTest2_1()
{
TEST2 test2;
test2.nValue = 11;
return test2;
}
TEST2 GetTest2_2( int nTemp )
{
TEST2 test2;
test2.nValue = 11;
if( nTemp > 100 )
{
test2.nValue = 111;
return test2;
}
return test2;
}
int main()
{
std::cout << "TEST1 - NRVO 사용" << std::endl;
{
auto test1_1 = GetTest1_1();
}
std::cout << std::endl;
std::cout << "TEST1 - NRVO 사용 불가" << std::endl;
{
auto test1_2 = GetTest1_2(101);
}
std::cout << std::endl;
std::cout << std::endl;
std::cout << "TEST2 - NRVO 사용" << std::endl;
{
auto test2_1 = GetTest2_1();
}
std::cout << std::endl;
std::cout << "TEST2 - move 생성자 사용" << std::endl;
{
auto test2_2 = GetTest2_2(101);
}
return 0;
}
< 결과 >
댓글