본문 바로가기

프로그래밍/C++

C++11 Emplace- SCOTT MEYERS 강의 후기



C++11 emplace 함수는 기존의 함수와는 또 다른 방식이다.



예를 들어


vector에 원소를 삽입할때 다음과 같이 할 수 있다.


vs.push_back("XYXY");


vs.emplace("XYXY");


작동은 동일하다.


하지만 내부적으로는 차이가 있는데


전자의 경우, 

문자열 임시변수가 만들어지고 복사 그리고 임시변수 파괴의 과정을 거친다.


하지만 후자의 경우

벡터 컨테이너 안에서 직접 생성한다.


std::vector::insert copies or moves the elements in to the container by calling copy constructor or move constructor.

while,

In std::vector::emplace elements are constructed in-place, i.e. no copy or move operations are performed.



http://www.cplusplus.com/reference/vector/vector/emplace/

http://egloos.zum.com/sweeper/v/3060229



그리고 벤치마킹을 보자



놀라운점은 컴파일러마다 이처럼 퍼포먼스의 차이를 보였다는 것이다.


또한 RValue, LValue 일때도 차이가 있으며


항상 emplace가 빠르지도 않다는 것이다.




마지막으로 스캇 아저씨가 말해준걸 요약하면


Emplacement는 생성자/소멸자 호출을 줄여준다.


이론적으로는 이 emplacement 가 insertion 보다 비용이 더 들진 않는다.


퍼포먼스에 크게 개의치 않다면 그냥 insert를 써라.


하지만 퍼포먼스를 생각한다면 한번 emplace를 Consider 해봐라.





vString.push_back("aaa");

0138C710  push        offset string "aaa" (013901D4h)  

0138C715  lea         ecx,[ebp-168h]  

0138C71B  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (01381339h)  

0138C720  mov         byte ptr [ebp-4],3  

0138C724  lea         eax,[ebp-168h]  

0138C72A  push        eax  

0138C72B  lea         ecx,[vString]  

0138C72E  call        std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::push_back (01381933h)  

0138C733  mov         byte ptr [ebp-4],2  

0138C737  lea         ecx,[ebp-168h]  

0138C73D  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (013814E2h)  



vString.emplace_back("aaa");

0138C742  push        offset string "aaa" (013901D4h)  

0138C747  lea         ecx,[vString]  

0138C74A  call        std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::emplace_back<char const (&)[4]> (0138196Ah)  



string 변수를 입력받는 벡터가 있고 push_back과 emplace_back 코드를 보자.

어셈블리 코드로만 봐도 생성자를 여러번 호출하는 push_back 보다 emplace_back이 월등히 낫다고 볼 수 있다.