Mi a legjobb algoritmus használata egy STL húr ha hash_map?

szavazat
44

Azt találtuk, a standard hash függvény VS2005 fájdalmasan lassú, amikor megpróbálja elérni a nagy teljesítményű megjelenés up. Melyek a jó példa a gyors és hatékony darabolási algoritmus, hogy meg érvénytelenítheti a legtöbb ütközés?

A kérdést 18/09/2008 22:58
a forrás felhasználó
Más nyelveken...                            


11 válasz

szavazat
7

Ez mindig attól függ, az adatkészlet.

Én egy volt meglepően jó eredményeket segítségével CRC32 a húr. Működik nagyon jó a legkülönbözőbb bemeneti készletek.

Sok jó CRC32 megvalósítások könnyű megtalálni a neten.

Edit: Majdnem elfelejtettem: Ez az oldal egy szép hash-függvény lő a teljesítmény számok és vizsgálati adatok:

http://smallcode.weblogs.us/ <- az oldalon lejjebb.

Válaszolt 18/09/2008 22:59
a forrás felhasználó

szavazat
8

Kiemelés egy boost :: hash könyvtár, amely néhány alapvető hash függvények leggyakoribb típus.

Válaszolt 18/09/2008 23:01
a forrás felhasználó

szavazat
18

Néhány régi kódot az enyém:

/* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */
static const size_t InitialFNV = 2166136261U;
static const size_t FNVMultiple = 16777619;

/* Fowler / Noll / Vo (FNV) Hash */
size_t myhash(const string &s)
{
    size_t hash = InitialFNV;
    for(size_t i = 0; i < s.length(); i++)
    {
        hash = hash ^ (s[i]);       /* xor  the low 8 bits */
        hash = hash * FNVMultiple;  /* multiply by the magic number */
    }
    return hash;
}

Ez gyors. Tényleg rohadt gyors.

Válaszolt 18/09/2008 23:01
a forrás felhasználó

szavazat
2

Egy klasszikus javaslatát egy húr hash, hogy át lehet lépni a betűk egyenként hozzáadjuk ASCII / unicode értékeket egy akkumulátorból, minden egyes alkalommal, megszorozva az akkumlátort prímszám. (Lehetővé téve túlfolyó a hash érték)

  template <> struct myhash{};

  template <> struct myhash<string>
    {
    size_t operator()(string &to_hash) const
      {
      const char * in = to_hash.c_str();
      size_t out=0;
      while(NULL != *in)
        {
        out*= 53; //just a prime number
        out+= *in;
        ++in;
        }
      return out;
      }
    };

  hash_map<string, int, myhash<string> > my_hash_map;

Nehéz, hogy gyorsabb, mint a nélkül kidobták adatokat. Ha ismeri a húrok lehet különböztetni csak néhány karaktert, és nem az egész tartalmat, amit tehetünk gyorsabb.

Lehet, hogy megpróbál-elve a hash érték jobb létre egy új alosztálya basic_string hogy emlékszik a hash értéket, ha az érték lesz számított túl gyakran. hash_map kell tennie, hogy a belső, mégis.

Válaszolt 18/09/2008 23:18
a forrás felhasználó

szavazat
6

Nekem használja a Jenkins hash levelet Bloom filter könyvtár, hogy nagy teljesítményt.

Részletek és a kód itt érhetők el: http://burtleburtle.net/bob/c/lookup3.c

Ez az, amit Perl használja annak tördelési művelet FWIW.

Válaszolt 18/09/2008 23:24
a forrás felhasználó

szavazat
6

Ha tördeljük rögzített szavak halmazának, a legjobb hash függvény gyakran tökéletes hash függvény . Ezek azonban általában megkövetelik, hogy a szavak halmazát próbál hash ismert fordításkor. Kimutatása kulcsszavakat egy lexer (és fordítási kulcsszavak tokenek) gyakori használata tökéletes hash függvények által generált olyan eszközök, mint gperf . Egy tökéletes hash is lehetővé teszi helyére hash_mapegy egyszerű tömb vagy vector.

Ha nem tördeljük rögzített szavak halmazának, akkor nyilván ez nem vonatkozik.

Válaszolt 19/09/2008 02:13
a forrás felhasználó

szavazat
0

Ha a húrok átlagosan hosszabb, mint egy gyorsítótár sor, de ezek hossza + előtaggal ésszerűen egyedülálló, fontolja hasing csak a hossza + első 8/16 karakter. (A hossza tartalmazza a std :: string objektumot magát, és ezért olcsó olvasható)

Válaszolt 19/09/2008 10:14
a forrás felhasználó

szavazat
63

Dolgoztam Paul Larson a Microsoft Research néhány hash megvalósítások. Ő megvizsgált több olyan húr tördelési funkció a különböző adatállományok és úgy találta, hogy egy egyszerű szorzás 101 és adjunk hurok meglepően jól működött.

unsigned int
hash(
    const char* s,
    unsigned int seed = 0)
{
    unsigned int hash = seed;
    while (*s)
    {
        hash = hash * 101  +  *s++;
    }
    return hash;
}
Válaszolt 20/09/2008 07:46
a forrás felhasználó

szavazat
2

Csináltam egy kis kereséssel, és vicces, Paul Larson kis algoritmus megjelent itt http://www.strchr.com/hash_functions ennek van a legkisebb ütközés bármely tesztelt számos feltétel, és ez nagyon gyorsan az egyik, hogy ez tekert vagy asztalra hajtott.

Larson, hogy az egyszerű szorzás 101 és add hurok felett.

Válaszolt 20/02/2012 00:41
a forrás felhasználó

szavazat
2

Python 3.4 tartalmaz egy új hash algoritmus alapján SipHash . PEP 456 nagyon informatív.

Válaszolt 19/03/2014 16:29
a forrás felhasználó

szavazat
0

Tól hash függvények egészen :

MurmurHash kapott elég népszerű, legalábbis játékfejlesztő körökben, mint egy „általános hash függvény”.

Ez egy jó választás, de lássuk, később, ha meg tudjuk általában jobban csinálni. Tovább jó választás, főleg, ha többet megtudni az adatok, mint „ez lesz egy ismeretlen számú bájt”, hogy roll a saját (lásd például győztese Chun válaszait, illetve Rune módosított xxHash / Murmur hogy specializálva 4 byte-os gombokat stb.). Ha tudja az adatokat, mindig próbálja látni, hogy ezt a tudást fel lehet használni a jó értelemben!

Anélkül több információt Azt javasoljuk MurmurHash mint egy általános célú , nem kriptográfiai hash függvény . A kis húrok (a mérete az átlagos azonosító programok) a nagyon egyszerű és híres djb2 és FNV nagyon jó.

Itt (adatméreteket <10 bájt) kiderül, hogy az ILP csípősség más algoritmusok nem kap megmutatni magát, és a szuper-egyszerű FNV vagy djb2 győzelem teljesítményt.

djb2

unsigned long
hash(unsigned char *str)
{
    unsigned long hash = 5381;
    int c;

    while (c = *str++)
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

    return hash;
}

FNV-1

hash = FNV_offset_basis
for each byte_of_data to be hashed
     hash = hash × FNV_prime
     hash = hash XOR byte_of_data
return hash

FNV-1A

hash = FNV_offset_basis
for each byte_of_data to be hashed
     hash = hash XOR byte_of_data
     hash = hash × FNV_prime
return hash

Egy megjegyzés a biztonság és rendelkezésre állás

Hash függvények a kódot sebezhető-megtagadási támadások. Ha egy támadó képes erő a szerver kezelni túl sok ütközés, a szerver nem képes megbirkózni kéréseket.

Néhány hash függvények, mint MurmurHash elfogadja a mag, amit tud nyújtani, hogy drasztikusan csökkentse a képessége támadók megjósolni a hash a szerver szoftver generál. Tartsd észben.

Válaszolt 24/12/2016 13:08
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more