Thinking Different




c++0x 부터 추가된 펑터 functor람다 lamda의 필요성을 vector 컨테이너의 sort 를 이용하여 알아보도록 한다



일반 함수 사용


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
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>
 
bool function_sort(int& a, int& b)
{
    return a > b;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> v;
    for (int i = 0; i < 10000000; ++i)
    {
        v.push_back(rand() % 2000);
    }
    
    auto StartTime = chrono::system_clock::now();
    
    sort(v.begin(), v.end(), function_sort); // 함수를 이용한 벡터 정렬
 
    auto EndTime = chrono::system_clock::now();
    chrono::milliseconds resultTime = chrono::duration_cast<chrono::milliseconds>(EndTime - StartTime);
    cout << resultTime.count() << "ms" << endl;
 
    return 0;
}




결과를 보면 844ms 가 나왔다.

똑같이 펑터를 사용하여 결과를 확인해보자





펑터 functor 사용


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
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>
 
class functor_sort
{
public:
    __inline bool operator()(int& a, int& b)
    {
        return a > b;
    }
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> v;
    for (int i = 0; i < 10000000; ++i)
    {
        v.push_back(rand() % 2000);
    }
    
    auto StartTime = chrono::system_clock::now();
    
    sort(v.begin(), v.end(), functor_sort()); // 펑터를 사용한 벡터 정렬
 
    auto EndTime = chrono::system_clock::now();
    chrono::milliseconds resultTime = chrono::duration_cast<chrono::milliseconds>(EndTime - StartTime);
    cout << resultTime.count() << "ms" << endl;
 
    return 0;
}



펑터로 사용하여 588ms 가 나왔다 약 300ms 정도 감소되었다.

똑같이 람다 사용한 부분을 보자





람다 lamda 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>
 
int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> v;
    for (int i = 0; i < 10000000; ++i)
    {
        v.push_back(rand() % 2000);
    }
    
    auto StartTime = chrono::system_clock::now();
    
    sort(v.begin(), v.end(), [](int& a, int& b)-> bool { return a > b; }); // 람다를 사용한 벡터 정렬
 
    auto EndTime = chrono::system_clock::now();
    chrono::milliseconds resultTime = chrono::duration_cast<chrono::milliseconds>(EndTime - StartTime);
    cout << resultTime.count() << "ms" << endl;
 
    return 0;
}




자 람다도 586ms 가 나왔다. 펑터랑 비슷한 속도로 일반 함수를 사용한 것보다 300ms 정도가 줄어들었다.

이런 결과가 나온 이유는 클래스 함수의 inline 화로 인하여 사용되는 처리 연산량이 확 줄었기 때문이다


펑터와 람다는 똑같이 inline을 사용하므로 속도는 똑같다. 하지만 펑터의 경우 따로 inline 클래스를 만들어주어야 되지만 람다의 경우는 람다식을 같이 작성하여 코드가 간결해지기 때문에 람다로 쓰는 것이 가장 좋을 것이다.