본문 바로가기

프로그래밍/Modern C++

[C++] Sort Vector VS Map

 

* 코드의 길이가 길어서 모바일은 불편할 수 있습니다.

 

테스트 환경 및 시나리오

컴파일러 Visual Studio 2019 (64bit Release)
CPU Intel i7-6700 3.40Ghz

 

총 3번의 테스트를 진행한다.

 

1. Search만 하는 경우

2. Insert와 Search를 병행하는 경우

3. Insert, Delete, Search를 병행하는 경우

 

2, 3번은 C++11의 random Engine를 이용한 난수 값으로 진행하며 Insert, Delete, Search 또한 난수를 통해 진행하는 만큼 어느 정도 미묘한 시간 차이가 있을 수 있음 또한 Vector에는 기본적으로 Reserve()를 미리 진행 후 테스트 진행

 

1) Search만 하는 경우

 

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
void TestOnlySearch() {
    std::vector<DWORD>       v;
    std::map<DWORD, DWORD>   map;
    std::uniform_int_distribution<DWORD> range(0, MAX_DATA);
 
    v.reserve(MAX_DATA);
    for (DWORD i = 0; i < MAX_DATA; ++i) {
        DWORD val = range(rnd);
        v.emplace_back(val);
        map[val] = val;
    }
    std::sort(v.begin(), v.end());
 
    {
        auto startTime = std::chrono::system_clock::now();
        for (DWORD i = 0; i < MAX_DATA; ++i) {
            DWORD val = range(rnd);
            std::lower_bound(v.begin(), v.end(), val);
        }
 
        auto endTime = std::chrono::system_clock::now() - startTime;
        int elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime).count();
 
        std::cout << "Sort Vector----> Only Search ElapsedTime: " << elapsedTime << "\n";
    }
 
    {
        auto startTime = std::chrono::system_clock::now();
        for (DWORD i = 0; i < MAX_DATA; ++i) {
            DWORD val = range(rnd);
 
            map.find(val);
        }
        auto endTime = std::chrono::system_clock::now() - startTime;
        int elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime).count();
 
        std::cout << "Map-----> Only Search ElapsedTime: " << elapsedTime << "\n";
    }
}

 

 

2) 생성-Search를 병행하는 경우

 

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
void TestInsertAndSearch() {
 
    std::vector<DWORD>       v;
    std::map<DWORD, DWORD>   map;
    std::uniform_int_distribution<DWORD> range(0, MAX_DATA);
    std::uniform_int_distribution<DWORD> Switch(01);
 
    v.reserve(MAX_DATA);
 
    {
        auto startTime = std::chrono::system_clock::now();
        for (DWORD i = 0; i < MAX_DATA; ++i) {
            DWORD val = range(rnd);
 
            switch (Switch(rnd)) {
            case 0: {
                v.emplace_back(val);
                std::sort(v.begin(), v.end());
                break;
            }
            case 1: {
                std::lower_bound(v.begin(), v.end(), val);
                break;
            }
            }
 
        }
 
        auto endTime = std::chrono::system_clock::now() - startTime;
        int elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime).count();
 
        std::cout << "Sort Vector----> Insert And Search ElapsedTime: " << elapsedTime << "ms\n";
    }
 
    {
        auto startTime = std::chrono::system_clock::now();
        for (DWORD i = 0; i < MAX_DATA; ++i) {
            DWORD val = range(rnd);
 
            switch (Switch(rnd)) {
            case 0: {
                map[val] = val;
                break;
            }
            case 1: {
                map.find(val);
                break;
            }
            }
 
        }
        auto endTime = std::chrono::system_clock::now() - startTime;
        int elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime).count();
 
        std::cout << "Map-----> Only Insert And Search ElapsedTime: " << elapsedTime << "ms\n";
    }
}

 

 

 

3) 생성-삭제-Search를 병행하는 경우

 

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
61
62
63
64
void TestInsertDeletedAndSearch() {
 
    std::vector<DWORD>       v;
    std::map<DWORD, DWORD>   map;
    std::uniform_int_distribution<DWORD> range(0, MAX_DATA);
    std::uniform_int_distribution<DWORD> Switch(02);
 
    v.reserve(MAX_DATA);
 
    {
        auto startTime = std::chrono::system_clock::now();
        for (DWORD i = 0; i < MAX_DATA; ++i) {
            DWORD val = range(rnd);
 
            switch (Switch(rnd)) {
            case 0: {
                v.emplace_back(val);
                std::sort(v.begin(), v.end());
                break;
            }
            case 1: {
                std::remove(v.begin(), v.end(), val);
                break;
            }
            case 2: {
                std::lower_bound(v.begin(), v.end(), val);
                break;
            }
            }
        }
 
        auto endTime = std::chrono::system_clock::now() - startTime;
        int elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime).count();
 
        std::cout << "Sort Vector----> Insert, Deleted And Search ElapsedTime: " << elapsedTime << "ms\n";
    }
 
    {
        auto startTime = std::chrono::system_clock::now();
        for (DWORD i = 0; i < MAX_DATA; ++i) {
            DWORD val = range(rnd);
 
            switch (Switch(rnd)) {
            case 0: {
                map[val] = val;
                break;
            }
            case 1: {
                map.erase(val);
                break;
            }
            case 2: {
                map.find(val);
                break;
            }
            }
        }
        auto endTime = std::chrono::system_clock::now() - startTime;
        int elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime).count();
 
        std::cout << "Map-----> Only Insert, Deleted And Search ElapsedTime: " << elapsedTime << "ms\n";
    }
}

 

 

후기

 

1번을 제외하고는 Map의 성능이 좋다고 볼 수 있다. 생성, 삭제의 빈도가 적고 Search만 진행한다면 Vector의 Binary_Search 또한 고려해볼 수 있는 내용이다.