new보단 make_shared를 사용하자. (but not always)

C++11에서는 총 3가지의 smart pointer를 지원한다. (shared_ptr, unique_ptr, weak_ptr)
이 때 make_shared를 사용할 때는
std::shared_ptr<T> ptr(new T(a,b,c))
보다는
std::shared_ptr<T> ptr = std::make_shared(a,b,c);
를 사용하는 것이 좋다.

그 이유는 전자의 경우에는 actual object를 생성하고, control block이 따로 생성되는데
후자의 경우에는 내부적으로 actual object와 control block을 함께 생성하기 때문이다. 따라서 후자가 좀더 효율적이라고 할 수 있다.
new의 호출 횟수만 봐도 전자는 2번, 후자는 1번이다. 그리고 후자의 경우가 당연히 locality와 memory fragmentation의 측면에서 더 좋다.
그러나 무조건 좋은 것만은 아니다.
전자의 경우에는 reference count가 0이 되면 actual object가 소멸되고, weak reference count 마저 0이 됐을 때 control block이 소멸되지만, 후자의 경우에는 reference count와 weak reference count가 모두 0이 됐을 때 비로소 actual object와 control block이 함께 소멸되게 된다.
http://itability.tistory.com/37
를 보면 장단점에 대해서 좀 더 알 수 있을 것이다. (이 블로그의 modern c++카테고리에 C++팁이 잘 정리되어있는 것 같다. )

http://egloos.zum.com/hellpme/v/1543080
를 보면 어떤 사람이 실제로 성능을 비교한 결과가 있다.
만약 최적화를 하지않았을 때 오히려 new보다 make_shared가 느린 이유는 make_shared의 경우에는 move constructor가 추가로 호출되기 때문인 것 같다. (~~ ptr = ~~ 이니까)
하지만 일반적으로 compiler가 RVO/NRVO 최적화를 진행하게 되면, 위와 같은 overload가 생기지 않으므로 make_shared가 new보다 빠르다.

http://stackoverflow.com/questions/9302296/is-make-shared-really-more-efficient-than-new
http://stackoverflow.com/questions/8843720/is-there-any-reason-not-to-use-stdmake-shared-when-constructing-objects

댓글