2009-09-19 5 views
0

나는 해시 테이블 (DotNET 사전 개체)을 스파 스 2 차원 데이터 집합의 일부로 사용하고 있습니다. 해시 테이블에있는 대부분의 항목은 서로 가깝게됩니다. 아마 100 ~ 10,000 개의 항목으로 끝날 것이고, 모두 0에 가깝게 흩어져 있습니다. 해쉬 테이블이 전체 정수 (32 비트) 범위에 퍼져있을 때 해시 테이블이 더 잘 수행된다는 것을 읽었습니다.정수 전체 범위에 매핑

연속 된 정수를 1 : 1 방식으로 크게 다른 값에 매핑하는 저렴한 방법이 있습니까? 나는 그것들을 다시 매핑 할 필요가 없다. 그것은 단지 일방적 인 것이다.

+1

먼저 실제 성능을 저하시키는 사람은 사전을 사용하는 데 문제가되지 않습니다. 실제 킬러는 다중 객체가 동일한 키를 가지고 있지만 사전을 가진 옵션이 아닌 테이블로 끝날 때입니다. 더 중요한 것은 임의의 핵심 가치 집합에 개체를 뿌리지 않는 것입니다. 1,2,3,4와 같은 세트는 잠재적으로 1보다 적은 memmory를 사용합니다. 1024 1089999 2^32-1 –

+0

.NET에서 Dictionary의 성능을 향상 시키려면 충돌 속도와 해싱 속도의 균형을 맞춰야합니다. 충돌없이 완벽한 해시를 가지려면 더 많은 시간이 소요됩니다. 마찬가지로 가장 빠른 해시 알고리즘은 더 많은 충돌을 갖습니다. 균형을 찾는 것이 핵심이며, BCL 팀은 신뢰할 수있는 업무를 수행했을 것입니다. 따라서 성능 문제가없는 한 BCL 팀에 의존하십시오. – nawfal

답변

1

Integer를 사용하는 대신 Integer에서 상속하는 클래스를 작성하고 GetHashCode 함수를 재정의하십시오. 이렇게하면 아무 것도 할 필요없이이 기능을 만들 수 있습니다! 내가 값을 확산하는 생각할 수

가장 쉬운 방법은 균등하게 그런 짓을하는 것입니다

public class MyInteger:Integer 
{ 
    public override int GetHashCode() 
    { 
     unchecked 
     { 
      return (int)Math.Pow(this,this); 
     } 
    } 
} 

니스와 최소의 노력을 유지하면서 균등 분할.

+0

@ Erich, 감사합니다. 그러나 이것은 가능한 모든 정수의 고유 한 매핑을 제공 할 것이라고 보장됩니까? –

+1

그것은 합리적으로 묶여 있다고 가정하지는 않지만 그렇게 될 것입니다. 또한 해시 테이블이 작동하는 방식에 대한 고유 한 매핑이 필요하지 않습니다. 그들은 당신의 속도가 아주 빠를만큼 충분히 퍼져 나갈 것입니다. 범위 외의 경우 int 인덱스가있는 배열 만 사용하는 것이 좋습니다. 각 빈 자리는 4 바이트 만 필요하므로 너무 크지 않습니다. 당신은 10,000이라는 것을 가장 높은 값으로 언급합니다. 따라서 전체 배열에 대해 40,000 바이트 또는 40k로 O (1) 검색 및 삽입 시간을 갖습니다. k 번째 메모리를 포기하고 싶다면 그렇게하는 것이 가장 좋습니다. – Erich

+0

좋은 점은,이 메모리가 아주 짧게 필요할 것이기 때문에이 메모리를 많이 쓰지 않아도됩니다. 이 접근 방식을 시도해보고 해시 테이블 방식보다 성능이 우수한 지 확인하십시오. 감사! –

1

키 집합의 최대 값 (kmax)을 알고있는 경우 상수 요소 (배율)로 확장하거나, 제품을 최대 정수 크기 (2^31 - 1) 미만으로 유지하는 고정 소수로 곱할 수 있습니다) :

가장 가까운 소수 즉

(2^30)/kmax로 : 확실히 주요 사용이 해시 테이블의 버킷 수와 동일하지 않습니다합니다. 여기

다른 솔루션입니다 : 닷넷 Random 클래스는 같은 씨앗에 대해 동일한 값을 생성합니다 때문에, 당신은 입력 키를 배포하는 것을 사용할 수 있습니다.

+0

흥미로운 솔루션입니다. 저는 정수가 낮을 것이라고 합리적으로 확신 할 수 있습니다.하지만이 클래스는 SDK에 들어가기 때문에이 것을 어려운 제약으로 삼을 것을 주저합니다. –

3

어쩌면 나는 당신이 말하는 것을 오해하고 있습니다. 그러나 사전은 이미 정수를 해시합니다. 미리 해시 할 필요가 없습니다. 기본 구현을 시험해보고 무의미한 사전 최적화를 시도하는 대신 어떻게 진행되는지보십시오.

+0

좋은 지적입니다! –

+0

Int32 형식을 디스 어셈블하는 경우 해시 코드는 숫자 자체 일뿐입니다. 해시 값이 전체 범위에 퍼져 있으면 해시 테이블이 더 잘 작동합니다. 물론 당신은 맞습니다. 둘 다 시도해보고 차이가 있는지 확인해야하지만 두 가지 방법을 모두 시도해보아야합니다. 정수를 다시 매핑 할 방법이 필요합니다. –

+0

@ David, 충분히 공평합니다. 여기에 몇 가지 해시 함수가 있습니다. http://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key –