빠른 문자열을 해싱 알고리즘을 저렴한 충돌 요금이 32 비트 정수[마감]
문제
나의 많은 관련이라는 것을 내가 하고 싶 빠른 검색을 한다.는"aardvark"항상"땅 돼지"도처에,그렇게 해싱하는 문자열과 재사용하는 정수 잘 작동 속도를 비교할 수 있습니다.전체 집합의 이름은 알 수 없음(그리고 시간에 따라 변경).What 빠른 문자열을 해싱 알고리즘을 생성하는 작은(32 16)비트 값이 낮은 충돌 평가?
보고 싶은 최적화된 구현하는 C/C++.
해결책
하의 FNV 개 해 귀하의 요구 사항을 충족합니다.그들은 빠른,그리고 생산을 매우 균등하게 배 출력이 있습니다.
다른 팁
잡음 해시 은 매우 좋다.
에 대한 고정된 문자열 설정을 사용하면 됩.
는 경우에 귀하의 문자열 설정 변경할 수 있는 기회를 제공합니다 hash function.는 항목에서 논의되었습기:
도 좋은 기사 에 eternallyconfuzzled.com.
Jenkins'One-at-a-Time 해쉬한 문자열은 다음과 같이 보일 것입니다:
#include <stdint.h>
uint32_t hash_string(const char * s)
{
uint32_t hash = 0;
for(; *s; ++s)
{
hash += *s;
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
다른 솔루션은 더 나은 수에 따라 사용 사례 구금 문자열.이 얼마나 기호 작동 예시패키지.
는 억류된 문자열은 문자열체는 값은 실제의 주소는 문자열이다.그래서 당신은 만들기를 억류된 문자열체를 확인하여 글로벌 테이블:는 경우 문자열은 거기에서,당신을 초기화 억류된 문자열의 주소는 문자열입니다.하지 않을 경우,당신은 그것을 삽입한 다음 초기화신의 억류된 문자열입니다.
이 의미는 억류된 두 문자열 내에서 동일한 문자열 값이 같은 주소입니다.그래서 만 N 의 수감되는 문자열에는 시스템의 특성은 다음과 같습니다.
- 느린 건설(필요 조회 및 가능한 메모리 할당)
- 필요한 글로벌 데이터 및 동기화의 경우에는 동시 스레드
- 비교 O(1),기 때문에 당신이 비교를 주지 않는,실제 문자열 바이트(즉,정렬,하지만 잘 작동 되지 않습니다 알파벳 일종).
환호
Carl
왜 당신은 단지 사용 을 향상 라이브러리? 의 해싱 기능을 사용하는 간단하고는 대부분의 재료에 부 곧 C++표준입니다.그것의 일부를 이미입니다.
Boost 해시만큼 쉽
#include <boost/functional/hash.hpp>
int main()
{
boost::hash<std::string> string_hash;
std::size_t h = string_hash("Hash me");
}
을 찾을 수 있습에서 향상 boost.org
그것은 결코 늦은 좋은 주고 난 사람들에 관심이 나의 결과입니다.
나는 데 필요한 해쉬 기능을 읽은 후 이 게시물을하고 연구의 비트에서 링크가 주어진 여기에,나는 이 변화의 다니엘 J 번스타인의 알고리즘을 사용하는 흥미로운 테스트:
unsigned long djb_hashl(const char *clave)
{
unsigned long c,i,h;
for(i=h=0;clave[i];i++)
{
c = toupper(clave[i]);
h = ((h << 5) + h) ^ c;
}
return h;
}
이 변화는 해시 문자열을 무시하는 경우 가장 필요로 해시 사용자는 로그인 자격 증명입니다.'clave'는'키'에서 스페인어입니다.나는 스페인어 그러나 그 어머니는 혀가 프로그램이 작성되었습니다.
만,나는 프로그램을 생성하는 사용자 이름에서'test_aaaa'에서'test_zzzz',그리고-할 긴 문자열-가 그들에게 임의의 도메인이트:'cloud-nueve.com','yahoo.com','gmail.com'및'hotmail.com'.따라서 그들 각각 다음과 같을 것이다:
test_aaaa@cloud-nueve.com, test_aaab@yahoo.com, test_aaac@gmail.com, test_aaad@hotmail.com and so on.
여기에서 출력의 테스트-'Colision entre XXX y XXX'는'충돌의 XXX XXX'.'palabras'의'단어가'및'총'은 동일한 모두어.
Buscando Colisiones... Colision entre 'test_phiz@hotmail.com' y 'test_juxg@cloud-nueve.com' (1DB903B7) Colision entre 'test_rfhh@hotmail.com' y 'test_fpgo@yahoo.com' (2F5BC088) Colision entre 'test_wxuj@hotmail.com' y 'test_pugy@cloud-nueve.com' (51FD09CC) Colision entre 'test_sctb@gmail.com' y 'test_iohw@cloud-nueve.com' (52F5480E) Colision entre 'test_wpgu@cloud-nueve.com' y 'test_seik@yahoo.com' (74FF72E2) Colision entre 'test_rfll@hotmail.com' y 'test_btgo@yahoo.com' (7FD70008) Colision entre 'test_wcho@cloud-nueve.com' y 'test_scfz@gmail.com' (9BD351C4) Colision entre 'test_swky@cloud-nueve.com' y 'test_fqpn@gmail.com' (A86953E1) Colision entre 'test_rftd@hotmail.com' y 'test_jlgo@yahoo.com' (BA6B0718) Colision entre 'test_rfpp@hotmail.com' y 'test_nxgo@yahoo.com' (D0523F88) Colision entre 'test_zlgo@yahoo.com' y 'test_rfdd@hotmail.com' (DEE08108) Total de Colisiones: 11 Total de Palabras : 456976
는 것은 나쁘지 않다,11 의 충돌의 456,976(물론을 사용하여 가득 차있는 32 비트로 테이블 길이).
실행하는 프로그램을 사용하여 5 문자,그가'에서 test_aaaaa'에서'test_zzzzz',실제로 실행의 메모리 건물이다.아래에 출력된다.'No hay memoria para insertar XXXX(insertadas XXX)'의'있지 않은 남아있는 메모리를 삽입하 XXX(XXX 삽입하는)'.기본적으로 malloc()에 실패했다는 점이다.
No hay memoria para insertar 'test_epjcv' (insertadas 2097701). Buscando Colisiones... ...451 'colision' strings... Total de Colisiones: 451 Total de Palabras : 2097701
을 의미하는 단 451 충돌에 2,097,701 문자열입니다.참고가 없는 경우가 있었 2 개 이상의 충돌당 코드입니다.는지 확인 그것은 좋은 해시 나를 위해,무엇이 필요로 변환하는 로그인 ID40 비트 고유 id 인덱.그래서 나는 이를 사용하여 로그인 자격증명을 변환하는 32 비트 해시고 사용하여 추가 8 비트를 처리하는 최대 255 개의 충돌당 코드를 찾고 테스트 결과는 것은 거의 불가능을 생성합니다.
희망이 사람에게 유용하다.
편집:
다음과 같이 테스트 상자가 AIX,나는 그것을 실행하는 사용 LDR_CNTRL=MAXDATA=0x20000000 를 제공 그것은 더 많은 메모리고 더 이상 실행,결과는 여기:
Buscando Colisiones...총 de Colisiones:2908 총 de Palabras:5366384
는 2908 후 5,366,384 하려고!!
매우 중요한:컴파일과 함께 프로그램-maix64(그래서 사용되는 64 비트),수의 충돌 0 에 대한 모든 경우에!!!
보 GNU 면 됩.
밥 젠킨스는 많은 해시 사용할 수 있는 기능, 모두는,빠르고 저렴한 충돌 요금입니다.
당신은 무엇을 볼 수 있습니다.NET 에서 사용하는 문자열입니다.GetHashCode()메서드를 사용하는 반사체.
나는 것을 짐작하는 Microsoft 상당한 시간 최적화이다.그들이 인쇄되는 모든 문제를 일괄적으로 너무는 그것을 변경될 수 있다.그래서 명확하게 그것은 그들의"성과 레이더를 조정";-)
것은 아주 사소한 포트는 C++너무 나는 생각했을 것입니다.
여기서 설명하는 방법으로 구현하는 자: http://www.devcodenote.com/2015/04/collision-free-string-hashing.html
조각에서 게시물:
고 말하는 경우에 우리는 캐릭터 설정은 자본의 영어 문자,그 길이의 캐릭터 설정은 26 일이 될 수 있습에 의해 표현된 숫자 0B 의 숫자 1,C 에 의하여 숫자 2 까 Z 에 의하여 숫자 25.지금할 때마다 우리는 원하는 지의 문자열 이 캐릭터 설정하는 고유 번호,우리가 수행하는 동 변환했던 것처럼 우리는 경우에는 바이너리 형식
CRC32.가에 대해 조의 링크에서 google 습니다.