C #에서 빠르고 잘 분산 된 해시 테이블을 구현하려고합니다. 임의의 해시 코드를 가져 와서 "제한"하여 해시를 인덱스하는 데 사용할 수있는 해시 제한 함수를 선택하는 데 문제가 있습니다. 지금까지 볼 수있는 두 가지 옵션이 있습니다.
한편으로 버킷에 항상 소수의 요소가 있는지 확인하고 해시를 제한하기 위해 버킷 수로 간단하게 모듈화 할 수 있습니다. 사실 이것은 .NET 사전이하는 일 입니다. 이 접근법의 문제점은 % 사용이 다른 작업에 비해 매우 느리다는 것입니다. 당신이 보면 Agner 안개 명령 테이블 ,
idiv
(%에 대해 생성됩니다 어셈블리 코드) 새로운 인텔 프로세서 ~ 25 사이클의 명령 대기 시간을 가지고있다. 약 3에 대한이를 비교하여mul
같은 비트 작전을 위해, 또는 1and
,or
또는xor
.반면에 버킷 수는 항상 2의 거듭 제곱을 가질 수 있습니다. 해시의 계수를 계산해야하므로 배열 외부에서 색인을 생성하려고 시도하지 않지만 이번에는 비용이 덜 듭니다. . 2의 거듭 제곱
% N
은 단지& (N - 1)
이므로, 제한은 1-2 사이클 만 소요되는 마스킹 작업으로 줄어 듭니다. 이것은 구글의 sparsehash에 의해 수행됩니다 . 이것의 단점은 좋은 해시를 제공하기 위해 사용자를 의지한다는 것입니다. 해시를 마스킹하면 해시의 일부가 차단되므로 해시의 모든 비트를 더 이상 고려하지 않습니다. 예를 들어, 사용자의 해시가 고르지 않게 분배되는 경우, 예를 들어 상위 비트 만 채워지거나 하위 비트가 일관되게 동일한 경우이 접근 방식은 충돌 률이 훨씬 높습니다.
나는 두 세계에서 가장 좋은 알고리즘을 찾고 있습니다 . 해시의 모든 비트를 고려하고 %를 사용하는 것보다 빠릅니다. 반드시 모듈러스 일 필요는 없으며, 범위 0..N-1
(N은 버킷의 길이 임) 에 있음을 보장하고 모든 슬롯에 대한 분포를 갖는 것이어야 합니다. 그러한 알고리즘이 존재합니까?
도움 감사합니다.
(2^N +/- 1)
, 참조 stackoverflow.com/questions/763137/...