본문 바로가기

C

c++ vector reserve를 통한 capacity 확보->속도향상

vector를 사용할 때

reserve로 capacity를 확보해 두면 속도가 향상된다

왜냐면 불필요하게 capacity를 확보하기 위해 원래 있던 elements들을 copy하고

재배치 하는 일이 없기 때문이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <vector>
#include <string>
 
class Cat
{
public:
    explicit Cat(std::string name) : mName{ std::move(name) } {
        std::cout << mName << "Cat constructor" << std::endl;
    };
    ~Cat() noexcept
    {
        std::cout << mName << "~Cat()" << std::endl;
    }
    Cat(const Cat& other) : mName(other.mName)
    {
        std::cout << mName << "copy constructor" << std::endl;
    }
    Cat(Cat&& other) noexcept: mName{ std::move(other.mName) }
    {
        std::cout << mName << "move Constructor";
    }
private:
    std::string mName;
};
 
int main()
{
    std::vector<int> nums{ 1,2,3,4,5 };
    nums.reserve(100000); // capacity 확보  (o(1)으로 접근 가능하게 함)
    // reserve를 크게 잡으면 move로 되기 때문에 빠름
    // reserve가 작으면 재할당 후 copy를 함
    std::cout << nums.size() << std::endl;
    std::cout << nums.capacity() << std::endl
    std::cout << sizeof(nums) << std::endl
    // 시작 포인터 정보(8bytes), size정보, capacity 정보
 
    nums.emplace_back(6);
    nums.emplace_back(6);
    nums.emplace_back(6);
    nums.emplace_back(6); 
    nums.emplace_back(6);
    nums.emplace_back(6);
    nums.emplace_back(6);
    std::cout << nums.size() << std::endl;
    std::cout << nums.capacity() << std::endl;
    std::cout << sizeof(nums) << std::endl// 여전히 nums는 24bytes
 
    std::vector<Cat> cats;
    //cats.reserve(5); // reserve 안 하면 copy 생김 (새로운 메모리 공간을 확보하지 못했기 때문에
    // kitty가 temp로 복사되며, 메모리를 확보 한 후, kitty와 nabi를 같이 넣음.
    // noexcept를 꼭 넣어준다.
    std::cout << "cats size : " << cats.size() << std::endl;
    cats.emplace_back("Kitty");
    std::cout << "cats size : " << cats.size() << std::endl;
    cats.emplace_back("nabi");
    std::cout << "cats size : " << cats.size() << std::endl;
 
 
}