2016-11-20 1 views
1

다른 개체에서 가져온 해시 코드는 x86 또는 x64 용으로 제작할 때와 다릅니다. 지금까지 내가 이렇게 내 자신의 해시 대부분의 기능을 구현 한 최대 :저는 x86이나 64 용으로 빌드 할 때 객체에 따라 다른 해시 코드를 얻는 것으로 나타났습니다.

int someIntValueA; 
int someIntValueB; 

const int SHORT_MASK = 0xFFFF; 
public override int GetHashCode() 
{ 
    return (someIntValueA & SHORT_MASK) + ((someIntValueB & SHORT_MASK) << 16); 
} 

윌, 긴의 값을 저장하고 그의 해시 코드는 64 비트 시스템에서뿐만 아니라 나에게 더 넓은 범위를 제공 얻거나 이게 나쁜 생각이야?

public override int GetHashCode() 
{ 
    long maybeBiggerSpectrumPossible = someIntValueA + (someIntValueB << 32); 
    return maybeBiggerSpectrumPossible.GetHashCode(); 
} 
+0

'int'를 반환하기 때문에 더 넓은 범위를 제공하지 않습니다. – Ryan

+0

@ Ryan 그게 내가 묻고있는 것입니다 : int는 언제나 그리고 언제나 int입니다 .32 또는 일부 상황에서 int64/long이됩니까? – user3488765

+1

당신이 물어 본 질문이 아닙니다. 이 질문에 대한 대답은 다음과 같습니다. C# int는 Int32의 동의어이며 스토리의 끝입니다. 포인터 크기의 정수는'IntPtr'이며, C#에서 수학 연산을 수행 할 수 없습니다. –

답변

7

아니요, 그보다 훨씬 나 빠질 것입니다.

int 값이 일반적으로 -30000에서 +30000 사이의 짧은 범위에 있다고 가정합니다. 그리고 대부분이 0에서 1000 사이의 중간에 있다고 가정 해 봅시다. 매우 일반적인 것입니다. 첫 번째 해시 코드를 사용하면 모두 해시 코드에 int의 비트가 들어있어 서로 간섭하지 않습니다. 일반적인 조건에서는 충돌 횟수가 0입니다.

그러나 길고도 트릭을하면 GetHashCode의 긴 구현 (x32 또는 하위 32 비트의 상위 32 비트)에 의존합니다. 따라서 새로운 구현은 느린 작성 방법 인 int1^int2 일뿐입니다. 어느 전형적인 시나리오에서 거의 모든 제로 비트, 따라서 장소 곳곳에 충돌이 있습니다.

1

당신이 제안하는 접근 방식은 더 좋은 결과를 내지 못할 것입니다. 그러나

...

SpookyHash은 저자가 생각했던 수학을 작업 할 때 어떤 64 비트 시스템에서 빠른 것이기 때문에, 64 비트 시스템에서 특히 빠르게 작동하도록 설계 예를 들어, xxHash (32)을 가지고 있습니다 32 비트 및 64 비트 계산을 위해 더 빠른 속도로 해시와 비슷한 품질을 제공하도록 설계된 64 비트 변형 및 64 비트 변형을 지원합니다.

서로 다른 기계에서 다른 산술 연산의 차이 성능을 사용하는 일반적인 아이디어가 유효합니다.

해시 계산에서 더 큰 중간 저장 공간을 사용한다는 일반적인 생각은 추가 비트가 후속 작업으로가는 한 유효한 입니다.

그래서 일반적으로 특정 구현에서이를 수행하지 못한 경우에도 대답은 '예'입니다.

이제 실제로 해시 코드 구현을 작성하려고 할 때 걱정할 필요가 있습니까?

글쎄요. 얼마 동안은 SpookyHash와 같은 알고리즘을 사용하는 것에 대해 매우 낙관적이었으며 해시가 많은 양의 소스 데이터를 기반으로 할 때 매우 잘 수행됩니다 (32 비트 시스템에서도). 그러나 다른 한편으로는 특히 작은 해시 기반 세트 및 사전과 함께 사용하면 환상적인 것보다 실제로 매우 진절머리 나게 더 좋을 수 있습니다. 따라서 한 가지 해결책 만은 아닙니다. 단지 두 개의 입력 정수를 사용하면 초기 솔루션이 xxHash 또는 SpookyHash와 같은 수퍼 애벌 런싱 알고리즘을 능가 할 것입니다. shift가 아닌 >> 16이 회전하면 더 잘 수행 할 수 있습니다 (재미있는 사실, 일부 불안감은 그것에 최적화되어 있습니다).하지만 64 비트와 32 비트 버전을 전혀 다룰 필요가 없습니다.

64 비트 및 32 비트에서 다른 접근 방식을 사용하여 큰 가능성을 발견 한 경우 특히 혼합 할 데이터가 많은 경우 (특히 blittable 형식 인 경우) (예 : string 또는 byte[]) 프레임 워크에 따라 long* 또는 int*을 통해 액세스 할 수 있습니다.

일반적으로 비트의 질문은 무시할 수 있지만 "이 해시 코드는 답변을 얻기 위해 많은 것을 거쳐야합니다. 더 좋게 만들 수 있습니까?" 어쩌면 그런 문제를 고려해야 할 때입니다.

관련 문제