2012-07-17 2 views
1

느린 equal_range 그러나 n 개의 선형 적으로 확장되지 않습니다 다음은 예상대로 :unordered_multimap :: 나는 unordered_multimap :: equal_range 평균 상수 복잡성 것으로 기대

#include <iostream> 
#include <tr1/unordered_map> 
#include <cstdlib> 

using namespace std::tr1; 
using namespace std; 

int main(){ 
     int n; 
     cin >> n; 
     unordered_map<int, int> um; 
     for(int i=0; i<n; ++i){ 
       um.insert(make_pair(i%100000, i)); 
       pair<unordered_map<int, int>::iterator,unordered_map<int,int>::iterator > t = um.equal_range(i); 
     } 
} 


$ g++ testbr.cpp 
$ time echo 10000 | ./a.out 

real 0m0.065s 
user 0m0.060s 
sys  0m0.003s 
$ time echo 100000 | ./a.out 

real 0m4.492s 
user 0m4.490s 
sys  0m0.003s 

인가 이 문제를 해결할 방법이 있습니까?

편집 : equal_range가 없으면 예상대로 조정됩니다.
또한 동일한 키 0 (와 항상 equal_range (0) 호출) 모든 요소를 ​​삽입하는 경우 동일한 문서의 범위가 평균적으로 O (count (k))라고 말하는 부스트 문서에도 불구하고 예상대로 확장됩니다 ...?

+0

'equal_range'행을 주석 처리 한 시간. 시간이 걸리는 것은'insert' 일 것입니다. 일반적으로 해시 맵이 왜 잘못되었는지 알아 내려면 각 버킷의 요소 수와 'bucket_count'를 살펴보십시오.이 예제가 고르게 분산 될 것으로 기대할 수 있지만 'max_bucket_count'를 눌렀을 것으로 생각됩니다. 나는 희망하지 않을 것이다. –

+0

항상 최적화 된 빌드를 프로파일 링해야합니다. '-O3'로 컴파일하면 어떻게됩니까? –

+0

-O3 100.000은 10.000보다 30 배 더 느립니다. 그렇기 때문에 좋지만 좋지는 않습니다. – user1531083

답변

1

이것은 libstdC++의 버그 인 것 같습니다. 어디서나 버그 보고서를 찾을 수는 없지만 #include <unordered_map>을 사용하고 -std=c++11을 컴파일하면 예상되는 동작이 나타납니다.

0

이것은 축척이 없습니다 O(n)이지만 O(n * n) (전화 할 때 std::equal_rangen 번)입니다.

std::equal_range을 안쪽 루프 밖으로 이동하십시오.

+0

부스트 문서에 따르면 equal_range는 평균 카운트 (k)에 있어야하는데, 이는 제 경우에는 1입니다! 이상하게도, 동일한 키에 모든 요소를 ​​삽입하면 훨씬 빠릅니다. count (k) == n – user1531083

+0

수는 1을 유지하지 않습니다. 총 실행 시간은 약입니다. '1 + 2 + 3 + ... + n'이다. – orlp

+1

@nightcracker : 'k'는 동일한 범위의 크기, 즉 해당 키가있는 컨테이너의 요소 수입니다. 키는'i % 100000'이며,이 예제에서'i