developer tip

초 고성능 C / C ++ 해시 맵 (테이블, 사전)

optionbox 2020. 10. 15. 07:43
반응형

초 고성능 C / C ++ 해시 맵 (테이블, 사전)


고성능 해시 맵 데이터 구조의 값을 구조화하려면 기본 키 (int, 어쩌면 long)를 매핑해야합니다.

내 프로그램에는 이러한 맵이 수백 개 있으며 각 맵에는 일반적으로 최대 수천 개의 항목이 있습니다. 그러나지도는 지속적으로 "새로 고침"또는 "이탈"됩니다. 수백만을 처리 상상 add하고 delete두 번째 메시지.

이 사용 사례에 맞는 데이터 구조를 가진 C 또는 C ++의 라이브러리는 무엇입니까? 또는 자신의 건물을 어떻게 추천 하시겠습니까? 감사!


나는 당신이 시도하는 것이 좋습니다 구글 SparseHash (또는 C11 버전 구글 SparseHash-C11를 )하고 필요에 맞는 있는지 확인합니다. 메모리 효율적인 구현과 속도에 최적화 된 구현이 있습니다. 오래 전에 벤치 마크를 수행했는데 속도 측면에서 사용할 수있는 최고의 해시 테이블 구현이었습니다 (그러나 단점이 있음).


이 사용 사례에 맞는 데이터 구조를 가진 C 또는 C ++의 라이브러리는 무엇입니까? 또는 자신의 건물을 어떻게 추천 하시겠습니까? 감사!

LGPL'd Judy 어레이를 확인하십시오 . 나 자신을 사용하지 않았지만 가끔 광고를 받았다.

STL 컨테이너 (std :: hash_map 등)를 벤치마킹 할 수도 있습니다. 플랫폼 / 구현 및 소스 코드 튜닝 (동적 메모리 관리 비용이 많이 드는만큼 사전 할당)에 따라 충분히 성능을 발휘할 수 있습니다.

또한 최종 솔루션의 성능이 솔루션 비용을 능가하는 경우 모든 것을 일반 어레이에 넣을 수있는 충분한 RAM이있는 시스템을 주문할 수 있습니다. 인덱스 별 액세스 성능은 타의 추종을 불허합니다.

추가 / 삭제 작업은 가져 오기 작업보다 훨씬 (100 배) 더 자주 발생합니다.

이는 먼저 알고리즘 개선에 집중하고 싶을 수도 있음을 암시합니다. 데이터를 읽지 않고 쓰기 만한다면 왜 데이터를 쓰나요?


기본적으로 boost::unordered_map(또는 tr1기타) 사용하십시오 . 그런 다음 코드를 프로파일 링하고 해당 코드가 병목인지 확인합니다. 그래야만 더 빠른 대체품을 찾기 위해 요구 사항을 정확하게 분석 할 것을 제안합니다.


다중 스레드 프로그램이있는 경우 인텔 스레드 빌딩 블록 라이브러리 에서 유용한 해시 테이블을 찾을 수 있습니다 . 예를 들어, tbb :: concurrent_unordered_map은 std :: unordered_map과 동일한 API를 갖지만 주요 함수는 스레드로부터 안전합니다.

또한 facebook의 어리석은 라이브러리를 살펴보십시오. 고성능 동시 해시 테이블스킵 목록이 있습니다.


안드로이드 소스에서 (따라서 Apache 2 라이센스가 부여됨)

https://github.com/CyanogenMod/android_system_core/tree/ics/libcutils

hashmap.c를보고 include / cutils / hashmap.h를 선택하십시오. 스레드 안전성이 필요하지 않으면 뮤텍스 코드를 제거 할 수 있습니다. 샘플 구현은 libcutils / str_parms.c에 있습니다.


khash는 매우 효율적입니다. 저자의 자세한 벤치 마크가 있습니다 : https://attractivechaos.wordpress.com/2008/10/07/another-look-at-my-old-benchmark/ 그리고 khash가 다른 많은 해시 라이브러리를 능가 함을 보여줍니다.


먼저 libmemcache와 같은 기존 솔루션이 필요에 맞는지 확인하십시오.

그렇지 않다면 ...

해시 맵이 귀하의 요구 사항에 대한 확실한 대답 인 것 같습니다. 키를 기반으로 o (1) 조회를 제공합니다. 대부분의 STL 라이브러리는 요즘 일종의 해시를 제공합니다. 따라서 플랫폼에서 제공하는 것을 사용하십시오.

해당 부분이 완료되면 솔루션을 테스트하여 기본 해싱 알고리즘이 요구 사항에 충분한 성능을 발휘하는지 확인해야합니다.

그렇지 않은 경우 인터넷에서 찾은 좋은 빠른 해싱 알고리즘을 탐색해야합니다.

  1. 좋은 오래된 소수 곱하기 알고리즘
  2. http://www.azillionmonkeys.com/qed/hash.html
  3. http://burtleburtle.net/bob/
  4. http://code.google.com/p/google-sparsehash/

이것이 충분하지 않은 경우 테스트 한 STL 컨테이너와 위의 해싱 알고리즘 중 하나에서 본 문제를 해결하는 해싱 모듈을 직접 롤링 할 수 있습니다. 결과를 어딘가에 게시하십시오.

오, 그리고 당신이 여러 개의 맵을 가지고 있다는 점이 흥미 롭습니다. 아마도 키가 속한 맵을 구별하고 하나의 거대한 해시에 모든 키 값 쌍을 추가하는 데 사용되는 상위 비트를 사용하여 64 비트 숫자로 키를 사용하여 단순화 할 수 있습니다. 기본 소수 해싱 알고리즘에서 완벽하게 잘 작동하는 10 만 개 정도의 기호가있는 해시를 보았습니다.

수백 개의 맵에 비해 솔루션의 성능을 확인할 수 있습니다. 메모리 프로파일 링 관점에서 더 나을 수 있다고 생각합니다.이 연습을 수행 할 수 있다면 어딘가에 결과를 게시하십시오.

나는 해싱 알고리즘보다 메모리의 지속적인 추가 / 삭제 (피할 수 있습니까?)와 애플리케이션의 성능에 더 중요한 CPU 캐시 사용 프로필이 될 수 있다고 생각합니다.

행운을 빕니다


기타 컨테이너 템플릿 에서 해시 테이블을 사용해보십시오 . 그것은 closed_hash_map구글의와 같은 속도에 관한 것입니다 dense_hash_map만, 사용 (포함 된 값에 대한 제한 없음)에 쉽게뿐만 아니라 다른 특전이있다.


나는 uthash를 제안 할 것이다 . 구조 #include "uthash.h"에 a UT_hash_handle추가 한 다음 구조에서 키 역할을 할 하나 이상의 필드를 선택하기 만하면됩니다 . 여기 에 성능에 대한 한마디 .


http://incise.org/hash-table-benchmarks.html gcc는 매우 잘 구현되어 있습니다. 그러나 매우 나쁜 표준 결정을 존중해야합니다.

재해시가 발생하면 모든 반복기가 무효화되지만 개별 요소에 대한 참조와 포인터는 계속 유효합니다. 실제 재해시가 발생하지 않으면 변경되지 않습니다.

http://www.cplusplus.com/reference/unordered_map/unordered_map/rehash/

이것은 기본적으로 표준이 구현이 연결 목록을 기반으로해야한다고 말합니다. 더 나은 성능을 가진 개방 주소 지정을 방지합니다.

Google 스파 스는 개방형 주소 지정을 사용하고 있다고 생각하지만 이러한 벤치 마크에서는 밀도가 높은 버전 만 경쟁 제품을 능가합니다. 그러나 희소 버전은 메모리 사용량면에서 모든 경쟁을 능가합니다. (또한 요소의 수에 대한 고원, 순수한 직선이 없습니다)

참고 URL : https://stackoverflow.com/questions/3300525/super-high-performance-cc-hash-map-table-dictionary

반응형