주의! 정확한 자료가 아닌 그냥 호기심 해결 기록입니다.
문득 코딩을 하다가 vector<int>
는 int 정적배열보다 얼마나 오버헤드가 생길까 싶어서
STL Container들의 크기를 확인해보고 싶어졌다.
sizeof 연산자로 확인결과 값을 1개 넣던 1,000,000개 넣던 같은 컨테이너면 같은 크기가 나왔다.
즉 값이 들어있는 전체 공간이 아니라 컨테이너 객체만의 크기를 반환해주는 듯 하다.
vector<int>
의 오버헤드는 메모리 32byte인것으로 추정되긴 하는데
이게 포인터의 크기와 같아서 heap에 할당되어있는 공간을 가리키는 stack의 포인터값 size를 리턴해준건 아닌가 싶기도 했었다.
근데 vector<bool>
의 경우 템플릿특수화 되어있어서 다르게 처리된다고 알고있었는데vector<bool>
은 48byte인걸 봐선 객체의 크기로 보는게 맞지 않나 싶다.
참고로 따로 확인해본 결과 vector<long long>
도 32byte로 나왔다.
또한 다른 컨테이너들은 32바이트가 아닌 각자 size가 있는 듯 해서 객체의 크기가 맞는 듯 하다.
다만 list는 다음 node 위치 기록하려면 적어도 포인터값 하나는 가져야하니까 32byte는 있어야 하는데 그보다도 적은 24byte라 뭐가뭔지 영…
처음 예상하기로는
- 컨테이너 객체를 만드는데 드는 시간
- 컨테이너 객체가 차지하는 메모리공간
- 객체의 멤버변수가 차지하는 스택영역의 메모리공간
- 객체의 멤버함수가 차지하는 코드영역의 메모리 공간
- deque의 보관테이블이나 해쉬컨테이너들의 해쉬테이블이 차지하는 메모리공간
- 보관된 데이터 자체는 heap에 할당하건 stack에 할당하건 총공간은 같을테니 패스
등등이 정적배열보다는 더 소비된다고 생각하긴 했는데 다른건 그렇다쳐도 list가 32byte도 안되는것 때문에 조사해보기 전보다 오히려 더 아리송해져버렸다…
아무튼 객체 자체의 크기로 판단한다면 일반적으로 현대의 컴퓨터수준에서는 메모리제약 때문에 int 정적배열을 고려해야 하는 일은 딱히 없는게 아닐까 싶다.
64bit운영체제에서 64bit 컴파일러로 확인한 결과이다.
결과
코드
#include <bits/stdc++.h>
using namespace std;
void main()
{
cout << "int형 크기\n";
int small = 1;
cout << "small : " << sizeof(small) << "byte\n";
int big = 2147483647;
cout << "big : " << sizeof(big) << "byte\n";
cout << "\nvector 크기\n";
vector<bool> vec_bool;
cout << "vec_bool : " << sizeof(vec_bool) << "byte\n";
vector<bool> vec_bool_10{ true };
cout << "vec_bool_10 : " << sizeof(vec_bool_10) << "byte\n";
vector<bool> vec_bool_10000(10000);
cout << "vec_bool_10000 : " << sizeof(vec_bool_10000) << "byte\n";
vector<int> vec_0;
cout << "vec_0 : " << sizeof(vec_0) << "byte\n";
vector<int> vec_10{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
cout << "vec_10 : " << sizeof(vec_10) << "byte\n";
vector<int> vec_10000(10000, 1);
cout << "vec_10000 : " << sizeof(vec_10000) << "byte\n";
vector<int> vec_1000000(1000000, 1);
cout << "vec_1000000 : " << sizeof(vec_1000000) << "byte\n";
cout << "\nlist 크기\n";
list<int> list_0;
cout << "list_0 : " << sizeof(list_0) << "byte\n";
list<int> list_10{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
cout << "list_10 : " << sizeof(list_10) << "byte\n";
list<int> list_10000(10000, 1);
cout << "list_10000 : " << sizeof(list_10000) << "byte\n";
list<int> list_1000000(1000000, 1);
cout << "list_1000000 : " << sizeof(list_1000000) << "byte\n";
cout << "\ndeque 크기\n";
deque<int> deque_0;
cout << "deque_0 : " << sizeof(deque_0) << "byte\n";
deque<int> deque_10{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
cout << "deque_10 : " << sizeof(deque_10) << "byte\n";
deque<int> deque_10000(10000, 1);
cout << "deque_10000 : " << sizeof(deque_10000) << "byte\n";
deque<int> deque_1000000(1000000, 1);
cout << "deque_1000000 : " << sizeof(deque_1000000) << "byte\n";
cout << "\nset 크기\n";
set<int> s;
cout << "set : " << sizeof(s) << "byte\n";
multiset<int> ms;
cout << "multiset : " << sizeof(ms) << "byte\n";
unordered_set<int> us;
cout << "unordered_set : " << sizeof(us) << "byte\n";
unordered_multiset<int> ums;
cout << "unordered_multiset : " << sizeof(ums) << "byte\n";
cout << "\nmap 크기\n";
map<int, int> m;
cout << "map : " << sizeof(m) << "byte\n";
multimap<int, int> mm;
cout << "multimap : " << sizeof(mm) << "byte\n";
unordered_map<int, int> um;
cout << "unordered_map : " << sizeof(um) << "byte\n";
unordered_multimap<int, int> umm;
cout << "unordered_multimap : " << sizeof(umm) << "byte\n";
}