2016-06-29 1 views
0

궁금합니다. 제 경우에 람다 함수를 사용하는 구현이 동등한 객체를 사용하는 구현보다 훨씬 빠른 이유는 무엇입니까? 10^4 값을 사용하면 빠른 속도는 1 초보다 훨씬 느리고 느린 속도는 10 초가 걸립니다. 10^5 밸류의 경우, 빠르기는 여전히 1 초 안에 완료되지만, 느린 것은 1 분이 걸립니다.왜 C++ Lambda 함수가 동등한 객체보다 compare 함수보다 훨씬 빠릅니다.

둘 중 하나를 정렬 할 때와 같은 방식으로 두 배열의 값을 정렬하려고합니다. 예를 들어 이해하기 쉽습니다. [5 1 2 0] [3 5 6 7] ~ [7 5 6 3]

인터넷을 사용하는 방법에는 여러 가지가 있습니다 하지만 그건 내가 묻기를 원하는 것이 아닙니다. 과부하 연산자()가있는 객체와 람다 함수가 "비교"인 객체를 사용하는 두 가지 구현을 수행했습니다.

아래 코드는 람다 함수 버전의 주석 처리가 제거되어 있습니다. 비교 객체를 사용하려면 "람다 함수를 사용하여 비교"에있는 내용을 주석 처리하고 "비교 객체를 사용하여 비교"를 주석 해제하십시오.

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <cstdlib> 
#include <ctime> 

void sortTwoVectorsByFirstVector(std::vector<float>& sortBySelf, std::vector<float>& sortByOther) 
{ 
    // init sort indices 
    std::vector <uint32_t> sortIndices(sortBySelf.size()); 
    for (uint32_t i = 0; i < sortIndices.size(); ++i) { 
     sortIndices[i] = i; 
    } 

    //******** begin: compare using compare object 
// struct CompareClass { 
//  std::vector<float> m_values; 
//  inline bool operator()(size_t i, size_t j) 
//  { 
//   return (m_values[i] < m_values[j]); 
//  } 
// } compareObject { sortBySelf }; 
// std::sort(sortIndices.begin(), sortIndices.end(), compareObject); 
    //******* end: compare using compare object 

    //******** begin: compare using lambda function 
    std::sort(sortIndices.begin(), sortIndices.end(), [&sortBySelf](size_t i, size_t j) {return sortBySelf[i] < sortBySelf[j];}); 
    //******** end: compare using lambda function 

    // collect the sorted elements using the indices 
    std::vector<float> sortedBySelf_sorted; 
    std::vector<float> sortByOther_sorted; 
    sortedBySelf_sorted.resize(sortBySelf.size()); 
    sortByOther_sorted.resize(sortBySelf.size()); 

    for (uint32_t i = 0; i < sortBySelf.size(); ++i) { 
     sortedBySelf_sorted[i] = sortBySelf[sortIndices[i]]; 
     sortByOther_sorted[i] = sortByOther[sortIndices[i]]; 
    } 

    sortBySelf.swap(sortedBySelf_sorted); 
    sortByOther.swap(sortByOther_sorted); 
} 

float RandomNumber() 
{ 
    return std::rand(); 
} 
int main() 
{ 
    int vectorSize = 100000; 
    std::vector<float> a(vectorSize); 
    std::vector<float> b(vectorSize); 

    std::srand(100); 
    std::generate(a.begin(), a.end(), RandomNumber); 
    std::generate(b.begin(), b.end(), RandomNumber); 

    std::cout << "started" << std::endl; 

    sortTwoVectorsByFirstVector(a, b); 

    std::cout << "finished" << std::endl; 
} 

이 거대한 성능 차이가 어디에서 유래되었는지 분명히 밝힐 수 있다면 멋질 것입니다.

+12

수동으로 작성된 클래스는 벡터를 복사하지만 람다 식은 복사하지 않습니다. –

+0

빠른 답변 감사합니다. – yar

답변

2

귀하 수동으로 작성된 클래스 복사 vector :

std::vector<float> m_values; //<< By value 

람다 표현식은 단지 그것을 참조 : 당신이합니다 (&없이) 사본 sortBySelf했다 경우

[&sortBySelf](size_t i, size_t j) {return sortBySelf[i] < sortBySelf[j];} 

는 그들은 가능성이 유사한 것 공연.

+0

감사합니다! 나는 이제 다른 방향으로 돌았 다. "std :: vector < float > m_values;" "std :: vector < float > & m_values;"로 변경하십시오. 하지만 내가 이해할 수없는 것은 : 복사가 초기화 될 때 한 번만 수행된다는 것입니다 (맞습니까?). 10^5 개 요소의 경우 수 초가 소요되지 않습니다. – yar

+0

@ user3022712 :'std :: sort'는 주어진 횟수만큼 * 주어진 펑터를 복사 할 수 있습니다. 적어도 functor'O (log (n))'를 복사하는 순진한 구현을 볼 수있었습니다. –

관련 문제