작성
·
63
1
return value가 scope를 벗어나면 유지가 될 필요성이 없어서 컴파일러가 move를 자동으로 해주는 RVO를 컴파일러를 믿고 의도적으로 노리는 것이 효율적인지
아니면 reference를 이용한 return값 최적화나 r-value에 대해 move를 직접 일으키는 방식의 코딩을 하는게 효율적인지
궁금합니다.
답변 2
1
안녕하세요? 질문&답변 도우미 durams입니다.
먼저 RVO와 NRVO를 간단하게 소개드리려합니다. 둘은 모두 불필요한 복사를 줄이기 위한 최적화 기술입니다.
RVO (Return Value Optimization) : 함수가 임시 객체 반환 시, 반환값이 바로 호출 위치에 생성되는 것.
NRVO (Named Return Value Optimization) : 함수가 지역 객체 반환 시, 반환값이 바로 호출 위치에 생성되는 것.
(엄밀히 말하면 강의에서 등장한 doSomething
함수는 NRVO를 보여주는 예시라고 할 수 있습니다)
둘을 나눠 소개드린 이유는, RVO는 C++17부터 mandatory(의무적)로 적용되지만, NRVO는 컴파일러의 판단 하에 선택적으로 적용되기 때문입니다. 즉, NRVO는 의도적으로 사용할 수 없습니다.
사실 RVO와 NRVO도 수많은 최적화 기술 중 하나의 예시에 불과하며, 현대 컴파일러가 수행하는 최적화는 프로그래머가 의도적으로 적용하는 것이 가능하지 않다고 보는것이 적절합니다. 기능 또는 수준에 따라 켜고 끄는 것이 가능한 경우는 있습니다만, 언제나 특정 최적화가 적용될 것이라고 기대하는 것은 적절하지 않습니다.
이에 대한 대안으로는 언급하신대로 참조 또는 r-value reference를 사용한 move semantics 구현이 있습니다. 컴파일러가 최적화 판단을 내리기 어려운 여러 상황들에 대해 프로그래머가 직접 최적화를 지원하는 방법이라고 할 수 있습니다.
질문자님께서 말씀해주신 두 가지 방법은 불필요한 복사를 제거한다는 점에서 목적은 같지만, 동작 방식과 판단 주체가 다릅니다. 한 가지 방법을 선택하시기보다는 둘을 조합해서 좋은 프로그램을 작성하시면 될 것 같습니다.
(관련 내용이 있는 제 이전 답변을 참고로 보셔도 좋을 듯 합니다)
강의 영상에 나온 코드와 비슷한 형태로 간단하게 예시를 들자면 아래와 같이 지역 객체를 반환하는 형태가 NRVO구요,
Fraction doSomething(){
Fraction temp(1, 2);
return temp;
}
아래와 같이 임시 객체를 반환하는 형태가 RVO입니다.
Fraction doSomething(){
return Fraction(1, 2);
}
대부분의 경우 위 설명으로 충분하지만, 사실 세부 조건들이 더 있긴 합니다. 더 깊게 설명드리기에는 강의 범위를 벗어나는것 같아, 더 관심있으시면 읽어보실만한 링크만 드리려합니다 : https://en.cppreference.com/w/cpp/language/copy_elision.html
당장은 참고용으로만 알아두셔도 충분한 내용들입니다.
0
안녕하세요, 인프런 AI 인턴입니다. 장준혁님.
질문하신 내용은 C++의 반환값 최적화(Return Value Optimization, RVO)와 관련하여 코드 효율성에 대한 중요한 주제입니다. RVO와 관련하여 컴파일러가 최적화를 수행하게 되면, 객체의 이동(move)나 복사(copy)에 필요한 비용을 줄일 수 있습니다. 이를 통해 성능 향상이 가능합니다.
RVO는 컴파일러가 자동으로 수행하는 최적화입니다. 따라서 코드를 작성할 때, 특별히 move나 복사를 최소화하려고 하지 않더라도 컴파일러가 적절하게 처리하여 성능을 최적화할 수 있습니다. 일반적으로 RVO는 컴파일러의 최적화 기능에 의존할 수 있으며, 대다수의 현대 컴파일러는 RVO를 적극적으로 사용합니다.
명시적으로 std::move
를 사용하여 객체를 이동하는 경우, 이는 RVO가 실패하거나 적용되지 않는 경우에 대비하는 것입니다. 그러나 종종 이런 명시적인 코드가 오히려 RVO의 최적화 기회를 방해하여, 예상치 못한 오버헤드를 발생시킬 수 있음을 주의해야 합니다.
더 자세한 관련 내용과 예제는 아래 게시물들을 참고해 주세요.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
RVO와 NRVO의 차이점이 잘 인지가 안되는데 ( 임시 객체와 지역객체 ) 이 부분 다시 설명이 가능할까요?