프로그래밍/기록, 개념, 용어
반환값 최적화 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<char, sizeof(Type)> read() const { std::array<char, sizeof(Type) temp; copy(temp.data(), source, size); return temp; } std::array<char, sizeof(Type)> read() const { return *reinterpret_cast<std::array<char, sizeof(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의 스택을 그대로 함수 안으로 끌어들여 직접 사용하는 것이다.
반응형