Knowhow/C, C++, CMake

STL vector 팁들

침닦는수건 2023. 9. 27. 20:39
반응형

.reserve() vs .resize()

이 두 개를 검색해보면 둘 다 vector의 크기를 사전에 할당해두는 함수들이라고 나오고 혼동하기 쉬운데, 전자는 초기값이 없고 후자는 있다는 차이 이상의 내용이 있다.

 

먼저 .reserve(A) 를 사용하면 A만큼의 메모리 공간을 해당 vector에 부여하고 잡아두는 것이 맞다. 하지만 메모리가 먼저 잡혀있는 것이지 실제 vector 사이즈가 A로 만들어지는 것이 아니다. 따라서 indexing이 안된다. 

 

따라서 .reserve()를 사용하는 경우는, push_back으로 vector에 계속 넣어줄 것인데 이 과정에서 사이즈를 명시하지 않으면 내부적으로 확장하고 복사하고 확장하고 복사하고 하면서 시간 잡아먹으니 이 시간 효율을 높이고 싶을 때 쓴다. 

 

반대로 .resize(A)는 A만큼의 vector를 미리 생성하고 초기값을 채워놓으므로 indexing이 된다. 실제로 메모리와 더불어 객체 생성까지 해두고 싶을 경우 resize를 쓰면 된다. 웬만하면 resize를 쓰는 것이 낫다.

 

특히 tbb를 이용해 병렬로 vector에 뭔가를 넣고 싶을 때 push_back을 쓴다면 mutex와 같이 써야하므로 indexing을 이용하는 것이 안전하다. 이럴 경우에는 무조건 resize를 써야 한다. 


.emplace_back() vs .push_back()

둘 다 vector 끝에 element를 추가해주는 method인데 차이가 있다.

push_back: 객체 자체를 넣어주는 식. 객체 자체를 넣으면 stack 영역에 임시 객체 생성-> 복사-> 임시 객체 추가 -> stack 영역에 임시 객체 소멸 과정으로 뭔가 작업이 많아서 오래 걸림. 

 

emplace_back: 객체를 넣건, 생성자 재료들을 넣든 돌아가는 식. 임시 객체 생성->임시 객체 추가->그대로 이동.

 

따라서 emplace_back 이 더 빠르다! 다만 emplace_back(생성자 재료들)도 돌아가기 때문에 잘못 넣었을 때도 이상하게라도 돌아갈 확률이 높음. 그래서 실수하지 않을 자신있으면 emplace_back 쓰는게 맞음.


sort

vector sorting하는 방법. 오름차순, 내림차순은 많이 쓰니 외워두면 좋다. 

sort(v.begin(), v.end()) 오름차순, sort(v.rbegin(), v.rend()) 내림차순이다. 


vector[] vs vector.at()

vector indexing할 때 두가지 방법이 가능하지만 후자인 .at()을 활용하는 것이 안전하다. 전자는 out of range index가 주어졌을 때 일단 동작하기 때문에 디버깅을 힘들게 만든 여지가 있지만 후자는 오류를 뱉는다.


find

vector 내 element 존재 여부 확인하는 방법.

#include <algorithm>

auto it = find(vector.begin(), vector.end(), element);
if (it == vector.end()) { continue; }
int idx = it - vector.begin();

shrink_to_fit

사용하면서 vector에 push_back, pop을 많이 사용했다면 현재 들어있는 element 양보다 더 큰 메모리가 잡혀있을 수 있다. 이 경우 vector.shrink_to_fit()을 호출해주면서 딱 맞는 메모리로 줄여줄 수 있다. (효율을 위해 가끔 해주면 좋은 기능)

#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> vec (100);
  std::cout << "1. capacity of vec: " << vec.capacity() << '\n';

  myvector.resize(10);
  std::cout << "2. capacity of vec: " << vec.capacity() << '\n';

  myvector.shrink_to_fit();
  std::cout << "3. capacity of vec: " << vec.capacity() << '\n';

  return 0;
}
// 1. capacity of vec: 100
// 2. capacity of vec: 100
// 3. capacity of vec: 10
반응형

'Knowhow > C, C++, CMake' 카테고리의 다른 글

CMakeLists.txt 작성 팁 1  (0) 2024.01.31
CMakeLists.txt 팩토링  (0) 2024.01.30
TBB 팁  (0) 2023.09.25
Boost serialization 팁들  (0) 2023.09.25
Boost serialization  (0) 2023.09.25