프로그래밍/기록, 개념, 용어

반환값 최적화 RVO, NRVO

제페 2015. 3. 1. 18:50
반응형

클래스 내에서 어떤 객체를 반환하고 싶다. 하지만 반환되는 과정의 오버헤드가 두려울 수 있다.


1
2
3
4
std::string get_name() const
{
    return std::string(my_name);
}



일단 저 구문을 보면 이렇게 될거라 생각할 수 있다. 3에서 임시 객체가 만들어지고, 그걸 반환하면서 복사 생성자가 또 호출될 것이다!

과거에는 그랬다. 하지만 근래의 컴파일러는 다음처럼 내용을 바꿔버린다.


1
2
3
4
void get_name(std::string& dest) const
{
    new(&dest)std::string{my_name};
}



이를 반환값 최적화(Return Value Optimization)라고 하며 이것에 의해 다음과 같은 구문들은 사실상 같은 것일 수도 있다.


std::array<charsizeof(Type)> read() const
{
    std::array<charsizeof(Type) temp;
 
    copy(temp.data(), source, size);
 
    return temp;
}
 
std::array<charsizeof(Type)> read() const
{
    return *reinterpret_cast<std::array<charsizeof(Type)>(source);
}


RVO는 근래의 컴파일러들은 거의 모두 지원한다.

하지만 이름이 있는 임시 객체는 최적화가 안 됐었는데 예를 들자면 다음과 같은 경우이다.


1
2
3
4
5
6
7
8
std::string get_name() const
{
    std::string temp;
    
    temp = name;
 
    return temp;
}


하지만 이름이 있는 임시 객체라도 RVO가 적용이 되더라도 문제가 없다고 발표했고 이것을 가리켜 NRVO(Named Return Value Optimization)라고 불렀다. 그냥 이름이 붙여진 RVO다. (Visual Studio는 2005 버전부터 이걸 지원했다고 한다.)


이 RVO의 아이디어는는 간단하다. 예를 들자면 


1
auto name = inst.get_name();


이런 구문이 있을때 name의 스택을 그대로 함수 안으로 끌어들여 직접 사용하는 것이다.

반응형