[ VC11-C++11 ] NRVO와 move 생성자에 의한 최적화

흥배 | 2012.10.25 01:41 | 조회 2117

아래 코드에서 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;

}

 

< 결과 >


twitter facebook me2day 요즘

게임&네이티브 팀블로그

rss
위로
2013.05
      01 02 03 04
05 06 07 08 09 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
RSS 2.0 | ATOM 0.3   
Total : 170,653
Yesterday : 2,633
Today : 1,442