
æåŸã«ãç§ã¯ããã«æ¥ãªããã°ãªããŸããã§ããã ã ã¯ã€ãã¯ããã·ã¥ããŒãã«ãäœæããŸãã ããšããèšäºãå
¬éããåŸãã ããã«é«éãªããã·ã¥ããŒãã«ãäœæããŸãã ããšããèšäºãå
¬éããŸããã ããã§ãæéã®ããã·ã¥ããŒãã«ã§ã®äœæ¥ãå®äºããŸããã ããã«ãããç§ãèŠã€ãããã¹ãŠã®ããã·ã¥ããŒãã«ãšæ¯èŒããŠãæéã®æ€çŽ¢ãå®è£
ããããšã«ãªããŸãã åæã«ãæ¿å
¥ããã³åé€æäœãéåžžã«é«éã«åäœããŸãïŒãã ãã競åä»ç€Ÿãããé«éã§ã¯ãããŸããïŒã
ã»ããã®æ倧æ°ãå¶éããŠãRobin Hoodããã·ã¥ã䜿çšããŸããã èŠçŽ ããã®çæ³äœçœ®ããXäœçœ®ããã倧ããè·é¢ã«ããå ŽåãããŒãã«ãå¢ããããã®å ŽåãåèŠçŽ ããã®æãŸããäœçœ®ã«ããè¿ããªãããšãæã¿ãŸãã ããã¯æ¬åœã«ããŸãããããã§ãã Xã®å€ã¯æ¯èŒçå°ãããããã·ã¥ããŒãã«ã®å
éšæ€çŽ¢ãµã€ã¯ã«ãããçšåºŠæé©åã§ããŸãã
ä»äºã§è©ŠããŠã¿ããå Žåã¯ããã¡ãããããŠã³ããŒãã§ããŸãã ãŸãã¯ãããœãŒã¹ã³ãŒããšäœ¿çšæ³ãã»ã¯ã·ã§ã³ãŸã§ã¹ã¯ããŒã«ããŸãã 詳现ãå¿
èŠãªå Žåã¯ãç¶ãããèªã¿ãã ããã
ããã·ã¥ããŒãã«ã¿ã€ã
ããã·ã¥ããŒãã«ã«ã¯å€ãã®çš®é¡ããããŸãã ç§èªèº«ã®ããã«ãç§ã¯éžæããŸããïŒ
- ãªãŒãã³ã¢ãã¬ãã·ã³ã°ã
- ç·åœ¢é
眮ã
- ããã·ã¥ããã³ãããã
- ã¹ãããã®æ°ã¯çŽ æ°ã§ãïŒãã ãããã®ç®çã®ããã«2ã®çŽ¯ä¹ã®æ°ã䜿çšã§ããããšã«æ°ä»ããŸããïŒã
- ã»ããã®æ倧æ°ãå¶éããŸãã
æåŸã®ãã€ã³ãã¯ãããã·ã¥ããŒãã«ã®åéã«ãããæ°èŠæ§ã ãšæããŸãã ãããç§ã®ãœãªã¥ãŒã·ã§ã³ã®é«ãããã©ãŒãã³ã¹ã®äž»ãªçç±ã§ãã ããããæåã«ãåã®æ®µèœã«ã€ããŠã話ããããšæããŸãã
ãªãŒãã³ã¢ãã¬ã¹æå®ãšã¯ãããã·ã¥ããŒãã«ãããŒã¿ã¹ãã¢ãšããŠé£ç¶é
åã䜿çšããããšãæå³ããŸãã ããã¯ãåèŠçŽ ãåå¥ã®ããŒãäžã«ããå Žåã®std::unordered_map
é¡äŒŒç©ã§ã¯ãããŸããã
ç·åœ¢å²ãåœãŠãšã¯ãèŠçŽ ãé
åã«æ¿å
¥ããããšããŠããŠãçŸåšã®ã¹ãããããã§ã«ãã£ã±ãã«ãªã£ãŠããå Žåã次ã®ã¹ãããã«ç§»åããããšãæå³ããŸãã ãã£ã±ãã«ãªã£ãŠããå Žåã¯ã次ã®ã¹ãããã䜿çšãããŸãã ãã®åçŽãªã¢ãããŒãã«ã¯ããç¥ãããæ¬ é¥ããããŸãããã»ããã®æ倧æ°ãå¶éããããšã§ä¿®æ£ããããšæããŸãã
ããã³ãããããã·ã¥ãšã¯ãç·åœ¢é
眮ã§ã¯ãåèŠçŽ ãã§ããã ãçæ³çãªäœçœ®ã«è¿ã¥ããããšããããšãæå³ããŸãã ããã¯ãããã€ãã®èŠçŽ ãæ¿å
¥ãŸãã¯åé€ããªããåšå²ã®èŠçŽ ã移åããããšã«ããè¡ãããŸãã ååã¯æ¬¡ã®ãšããã§ãããªãããªèŠçŽ ãããããååŸãã貧ããèŠçŽ ã«è»¢éããŸãã ããããããã³ãããã®ååã®ç±æ¥ã§ãã ãªããã¢ã€ãã ã¯ãçæ³çãªæ¿å
¥ãã€ã³ãã®è¿ãã§ã¹ããããåãåãèŠçŽ ã§ãã 貧匱ãªèŠçŽ ã¯ãçæ³çãªæ¿å
¥ãã€ã³ãããã¯ã»ã©é ãã§ãã æ°ããèŠçŽ ãæ¿å
¥ãããšããçæ³çãªäœçœ®ããã©ãã ãé¢ããŠããããæ°ããŸãã çŸåšã®èŠçŽ ãããé ãå Žåã¯ãçŸåšã®èŠçŽ ã®ä»£ããã«æ°ããèŠçŽ ãé
眮ãããã®èŠçŽ ã®æ°ããå ŽæãèŠã€ããããšããŸãã
ã¹ãããã®æ°ã¯çŽ æ°ã§ããããã·ã¥ããŒãã«ã®åºã«ãªãé
åã®ãµã€ãºã¯çŽ æ°ã§ãã ããã¯ãããšãã°ã5ã¹ããããã11ã¹ãããã23ã¹ããããã47ã¹ããããªã©ã«æ¡å€§ã§ããããšãæå³ããŸãã æ¿å
¥ãã€ã³ããèŠã€ããå¿
èŠãããå Žåã¯ãã¢ãžã¥ãæŒç®åã䜿çšããŠèŠçŽ ã®ããã·ã¥å€ãã¹ãããã«å²ãåœãŠãŸãã å¥ã®ãªãã·ã§ã³ã¯ãé
åã®ãµã€ãºã2ã®çŽ¯ä¹ã«çããããããšã§ãã 以äžã§ã¯ãããã©ã«ãã§çŽ æ°ã䜿çšããçç±ãšãäž¡æ¹ã®ãªãã·ã§ã³ã䜿çšããããšãæšå¥šãããå Žåã«ã€ããŠèª¬æããŸãã
ã»ããã®æ倧æ°ãå¶éãã
åºæ¬ãç解ããã®ã§ãä»åºŠã¯ãœãªã¥ãŒã·ã§ã³ã説æããŸããããããŒãã«ãæ€çŽ¢ããã¹ãããã®æ倧æ°ãå¶éãããšãé
åã®ãµã€ãºã倧ãããªããŸãã
æåã¯ããã®éãéåžžã«å°ãããããšãã°4ã«ããããšã§ãããã€ãŸããæ¿å
¥ãããšãã«ãæåã«çæ³çãªã¹ããããè©ŠããŸããããŸããããªãå Žåã¯ã次ã«ã次ã«ã次ã«ã次ã«ããã¹ãŠããã£ã±ãã«ãªã£ããããã®åŸãããŒãã«ãæ¡å€§ããŠãèŠçŽ ãããäžåºŠæ¿å
¥ããããšããŠããŸãã ããã¯å°ããªããŒãã«ã§ããŸãæ©èœããŸãã ãããã倧ããªããŒãã«ã«ã©ã³ãã ãªå€ãæ¿å
¥ãããšããããã®4ã€ã®ã»ããã§åžžã«å€±æããŸããããŒãã«ãã»ãšãã©ç©ºã§ãã£ãŠããããŒãã«ã®ãµã€ãºã倧ããããå¿
èŠããããŸãã
æçµçã«ãäžéãlog2ïŒnïŒã«çããå ŽåïŒnã¯ããŒãã«å
ã®ã¹ãããæ°ïŒãåå²ãåœãŠã¯çŽ2/3ããã£ã±ãã«ãªã£ããšãã«ã®ã¿å®è¡ãããããšãããããŸããã ããã¯ãã©ã³ãã ãªå€ãæ¿å
¥ãããšãã§ãã ãããŠãé£ç¶ããå€ãæ¿å
¥ãããšãããŒãã«å
šäœã«èšå
¥ã§ãããã®å Žåã«ã®ã¿åé
åžãããŸãã
ããããçµéšçã«èŠã€ãã£ã2/3ã®ãããå€ã«ãããããããåé
åžã¯ããŒãã«ã®60ïŒ
ã®ã«ãã¬ããžã§éå§ãããŸããã ææ-55ïŒ
ã§ãã ãããã£ãŠãããŒãã«max_load_factor
ã0.5ã«max_load_factor
ãŸãã ããã¯ãã»ããæ°ã®å¶éã«éããŠããªãå Žåã§ãã50ïŒ
ã§æºãããããšããŒãã«ãå¢å ããããšãæå³ããŸãã å®éã«ãµã€ãºã倧ãããããšãã«ããŒãã«ã®åé
åžãä¿¡é Œã§ããããã«ããããè¡ããŸããïŒ1000åã®èŠçŽ ãæ¿å
¥ãããããã®ããã€ããåé€ããŠãããåãéãããäžåºŠæ¿å
¥ãããšãããŒãã«ãããã§ãªãããšãã»ãŒå®å
šã«ç¢ºä¿¡ã§ããŸãåé
åžãããŸããã æ£ç¢ºãªçµ±èšæ
å ±ã¯ãããŸããããããŸããŸãªãµã€ãºã®æ°åã®ããŒãã«ãäœæããããããä¹±æ°ã§åããç°¡åãªãã¹ããå®è¡ããŸããã åèšã§æ°ååã®æ°åãæ¿å
¥ããŸããããè² è·ä¿æ°ã0.5æªæºã®ååæ£ã1åã ãçºçããŸããïŒ48ïŒ
ã®å
å¡«ã§ããŒãã«ãå¢å ããŸããïŒã ãã®ããããã®ãããªã¡ã«ããºã ãä¿¡é Œã§ããŸããäºæããªããšãã«ãéåžžã«ãéåžžã«ãéåžžã«ãŸãã«åé
åžããŸãã
äžè¬ã«ãããŒãã«ã®å¢å ãå¶åŸ¡ããå¿
èŠããªãå Žåmax_load_factor
å€ãèªç±ã«é«ãmax_load_factor
ãŸãã æããããšãªã0.9ãŸã§èšå®ïŒããã³ããããšã»ããæ°ã®å¶éã®çµã¿åããã«ããããã¹ãŠã®æäœã®é«éæ§ã確ä¿ãããŸãã ãã ããå€1.0ãå²ãåœãŠãªãã§ãã ãããæ¿å
¥ãéå§ãããšãããŒãã«ã®åèŠçŽ ãæåŸã®æ®ãã®ã¹ããããæºããããã«ç§»åãå§ããå ŽåããããŸãã ããšãã°ãæåŸã®ç©ºã®ã¹ããããé€ããŠãæåŸã®ã¢ã€ãã ãé
眮ããããã¹ãŠã®ã¹ãããã¯ãã§ã«äœ¿çšãããŠããŸãã 次ã«ãèŠçŽ ãæ¿å
¥ãããæåã®ã¹ãããã«èŠçŽ ãæ¿å
¥ããŸããããã®èŠçŽ ã¯ãã§ã«äœ¿çšãããŠããŸãã æ¢åã®èŠçŽ ã2çªç®ã®ã¹ãããã«ç§»åãããããã3çªç®ã®èŠçŽ ã«ç§»åããå¿
èŠããããŸãããã§ãŒã³äžã§ããŒãã«ã®æåŸãŸã§ç§»åããŸãã ãã®çµæãæåã®èŠçŽ ãé€ããã¹ãŠã®èŠçŽ ãçæ³çãªäœçœ®ããåãã¹ãããã«ããããŒãã«ãåŸãããŸãã æ€çŽ¢ã¯äŸç¶ãšããŠé«éã§ãããæåŸã®æ¿å
¥ã«ã¯æéãããããŸãã è¿ãã«ç©ºãã¹ããããããã€ãããå Žåãæ¿å
¥ãããèŠçŽ ã¯ããã»ã©å€ãã®é£äººã移åããŸããã
max_load_factorã ãã»ããæ°ã®å¶éã«æ±ºããŠéããªãã»ã©äœãå€ã«èšå®ããå Žåããªãäœãå¶éããªãã®ã§ããïŒ ãã®å¶éã®ãããã§ã埮åŠãªæé©åãå®è£
ã§ããŸããããŒãã«ãåãã£ãã·ã¥ããŠã1000ã¹ããããååŸãããšããŸãããã ç§ã®å ŽåãããŒãã«ã¯1009ã«ãªããŸããããã¯æãè¿ãçŽ æ°ã§ãã 1009ã®2é²å¯Ÿæ°ã¯10ã«äžžãããããããã»ããã®æ°ã10ã«å¶éããŸãã ããã§ãããªãã¯ãé©çšããŸãã1009ã¹ãããã®é
åã®ä»£ããã«ã1019ã®é
åãäœæããŸããããããä»ã®ãã¹ãŠã®ããã·ã¥æäœã§ã¯ã1009ã¹ããããããªããšä»®å®ããŸãã ããã§ã2ã€ã®èŠçŽ ãã€ã³ããã¯ã¹1008ã§ããã·ã¥ãããå ŽåãæåŸã«ç§»åããŠã€ã³ããã¯ã¹1009ã«æ¿å
¥ã§ããŸããã€ã³ããã¯ã¹ã®ç¯å²ããã§ãã¯ããïŒå¢çãã§ãã¯ïŒå¿
èŠã¯ãããŸãããã»ããã®æ°ã®å¶éã«ãããã€ã³ããã¯ã¹1018ãè¶
ããããšã¯ã§ããŸãããæåŸã®ã¹ãããã«å
¥ãããèŠçŽ ã11åããå ŽåãããŒãã«ãå¢å ããããããã¹ãŠã®èŠçŽ ãç°ãªãã¹ãããã«ãã£ãã·ã¥ãããŸãã å¢çãã§ãã¯ããªããããã³ã³ãã¯ããªå
éšã«ãŒããçºçããŸãã æ€çŽ¢æ©èœã¯æ¬¡ã®ããã«ãªããŸãã
iterator find(const FindKey & key) { size_t index = hash_policy.index_for_hash(hash_object(key)); EntryPointer it = entries + index; for (int8_t distance = 0;; ++distance, ++it) { if (it->distance_from_desired < distance) return end(); else if (compares_equal(key, it->value)) return { it }; } }
ããã¯åºæ¬çã«ç·åœ¢æ€çŽ¢ã§ãã ã³ãŒãã¯å®å
šã«ã¢ã»ã³ãã©ãŒã«å€æãããŸãã ãã®ã¢ãããŒãã¯ã次ã®2ã€ã®çç±ã§åçŽãªç·åœ¢é
眮ãããåªããŠããŸãã
- ã€ã³ããã¯ã¹å€æŽã®ç¯å²ã®æ€èšŒã¯ãããŸããã 空ã®ã¹ãããã®
distance_from_desired
å€ã¯-1ã§ãããããããã¯å¥ã®èŠçŽ ãèŠã€ããããšã«äŒŒãŠããŸãã - ã«ãŒãã§ã¯ãlog2ïŒnïŒå以äžã®å埩ã¯å®è¡ãããŸããã éåžžãããã·ã¥ããŒãã«ã§æ€çŽ¢ããå Žåãææªã®æéã®è€é床ã¯OïŒnïŒã§ãã ç§ã®ããŒãã«ã§ã¯-OïŒlog nïŒã ããã¯å€§ããªéãã§ãã ç¹ã«ãç·åœ¢é
眮ã§ã¯ãèŠçŽ ãã°ã«ãŒãåããããããããææªã®ã±ãŒã¹ãæãŸããããšãèæ
®ããŠãã ããã
ç§ã®ã¡ã¢ãªãªãŒããŒãããã¯èŠçŽ ããšã«1ãã€ãã§ãã distance_from_desired
ãint8_t
ã«æ ŒçŽãint8_t
ã ã€ãŸããæ¿å
¥ãããèŠçŽ ã®ã¿ã€ãïŒã¿ã€ãã®ã¢ã©ã€ã³ã¡ã³ãïŒãäœçœ®åãããããšãã«ã1ãã€ããåã蟌ãŸããŸãã ãããã£ãŠãæŽæ°å€ãæ¿å
¥ãããšã1ãã€ããããã«3ãã€ãã®ããã£ã³ã°ãåãåãããã®çµæãåèŠçŽ ã®4ãã€ãã®ãªãŒããŒãããã解æŸãããŸãã ãã€ã³ã¿ãŒãæ¿å
¥ãããšãããã£ã³ã°ã¯ãã§ã«7ãã€ãã«ãªãã8ãã€ãã®ãªãŒããŒããããçºçããŸãã ãã®åé¡ã解決ããããã«ãã¡ã¢ãªäœ¿çšã¹ããŒã ãå€æŽãããªãã·ã§ã³ãæ€èšããŠããŸããããã®å Žåãæ€çŽ¢ããšã«1ã€ã§ã¯ãªã2ã€ã®ãã£ãã·ã¥ãã¹ãçºçããããšãæããŠããŸãã ãããã£ãŠãã¡ã¢ãªãªãŒããŒãããã¯ãèŠçŽ ããšã«1ãã€ã+ããã£ã³ã°ã§ãã ãŸããããã©ã«ãã®max_load_factor
å€ã0.5ã®å ŽåãããŒãã«ã¯25ã50ïŒ
ããæºããããªããããç·ãªãŒããŒãããã¯ããã«å€§ãããªããŸãã ã¡ã¢ãªãç¯çŽããããã«ãæããããšãªãmax_load_factor
ã0.9ã«å¢ããããšãã§ããŸãããããã¯é床ã®ããããªäœäžã«ã€ãªããããšãæãåºãããŠãã ããã
æ€çŽ¢ããã©ãŒãã³ã¹
ããã·ã¥ããŒãã«ã®ããã©ãŒãã³ã¹ã調ã¹ãã®ã¯ç°¡åã§ã¯ãããŸããã å°ãªããšãããã®ãããªç¶æ³ã§ã¯é床ã枬å®ããå¿
èŠããããŸãã
- ããŒãã«å
ã®ã¢ã€ãã ãæ€çŽ¢ããŸãã
- ããŒãã«ã«ãªãã¢ã€ãã ãæ€çŽ¢ããŸãã
- ä¹±æ°ã®ã°ã«ãŒããæ¿å
¥ããŸãã
reserve()
åŒã³åºããåŸãä¹±æ°ã®ã°ã«ãŒããæ¿å
¥ããŸãã- ã¢ã€ãã ã®åé€ã
ãããŠããããã®ç¶æ³ã®ããããã¯ãç°ãªããµã€ãºã®ç°ãªãããŒãšå€ã§è¿œãæãããå¿
èŠããããŸãã ããŒãšããŠãæŽæ°å€ãŸãã¯æååå€ã䜿çšããå€ã®ã¿ã€ãã¯4ã32ãããã³1024ã§ããæååã§ã¯ãã»ãšãã©ãã¹ãŠã®ããã·ã¥ããŒãã«ã§åãããã·ã¥é¢æ°ãšæ¯èŒæŒç®åã®ãªãŒããŒãããã枬å®ãããããæŽæ°å€ã奜ã¿ãŸãã
ããŒãã«ã«èŠçŽ ãããå Žåãšãªãå Žåã®äž¡æ¹ã§æ€çŽ¢ããã¹ãããå¿
èŠããããŸãããããã®å Žåãããã©ãŒãã³ã¹ãåçã«å€åããå¯èœæ§ãããããã§ãã ããšãã°ã google::dense_hash_map
ïŒä¹±æ°ã§ã¯ãªãïŒã«google::dense_hash_map
ãã¹ãŠã®æ°å€ãæ¿å
¥ããäžè¶³ããŠããèŠçŽ ãæ€çŽ¢ãããšãå°é£ãªç¶æ³ã«çŽé¢ããŸããã äºæ³å€ã«ãããã·ã¥ããŒãã«ã¯éåžžããã500åé
ããªããŸãã ããã¯æ¥µç«¯ãªã±ãŒã¹ã§ã-2ã®çŽ¯ä¹ã䜿çšããŠããŒãã«ã®ãµã€ãºãèšå®ããŸãã ãããããä¹±æ°ãšé£ç¶ãããã®ã䜿çšããŠæž¬å®ãå®è¡ããå¿
èŠããããŸããããå€ããããšã°ã©ããå€æããŸããã ãããã£ãŠãç§ã¯èªåèªèº«ãä¹±æ°ã®ã¿ã«å¶éããç¹å®ã®ãã¿ãŒã³ã«ããããã©ãŒãã³ã¹ã§å€±æããç¶æ³ã®çºçãæé€ããŸãã
æåã®ã°ã©ãã¯ãè¡šã«ååšããèŠçŽ ã®æ€çŽ¢ã§ãã

ã°ã©ãã¯éåžžã«ã¿ã€ãã§ãã flat_hash_map
ã¯ç§ã®æ°ããããã·ã¥ããŒãã«ã§ãã flat_hash_map_power_of_two
ã¯åãããŒãã«ã§ãããé
åã®ãµã€ãºã¯çŽ æ°ã§ã¯ãªã2ã®ã¹ãä¹ã§æ±ºãŸããŸãã ã芧ã®ãšããã2çªç®ã®ãªãã·ã§ã³ã¯ã¯ããã«é«éã§ãããã®çç±ã«ã€ããŠã¯åŸã§èª¬æããŸãã dense_hash_map
ã¯google::dense_hash_map
ã§ãç§ãèŠã€ããæéã®ããã·ã¥ããŒãã«ã§ãã sherwood_map
ã¯ããé«éããã·ã¥ããŒãã«ãäœæããŸãããã®å€ãããŒãã«ã§ãã ç§ã®æ¥ããããããšã«ãããã¯å¹³å¡ãªçµæã瀺ããŸãã... std::unordered_map
ããã³boost::unordered_map
ãã¹ãŠã¯ååããæããã§ãã multi_index
ã¯boost::multi_index
ã§ãã
ãã®ã°ã©ãã«ã€ããŠå°ã説æããŸãã Y軞-1ã€ã®èŠçŽ ã®æ€çŽ¢ã«è²»ããããããç§æ°ã Google Benchmarkã䜿çšããŸãããããã¯ã table.find()
é¢æ°table.find()
åŒã³åºãããããã§ããåæ°ãã«ãŠã³ãããŸãã å埩ã®åèšæéã¯ãã®æ°ã§é€ç®ãããããç§ãååŸãããŸãã å¿
èŠãªãã¹ãŠã®ããŒãããŒãã«ã«ååšããŸãã X軞ã«ã€ããŠã¯ãããã©ãŒãã³ã¹ã®å€åãããè¡šããŠããããã察æ°ç®çã䜿çšããŸããã ããã«ããã®ãããªã¹ã±ãŒã«ã§ã¯ãããŸããŸãªãµã€ãºã®ããŒãã«ã®ããã©ãŒãã³ã¹ãè©äŸ¡ã§ããŸããå°ããªããŒãã«ã«é¢å¿ãããå Žåã¯ãã°ã©ãã®å·ŠåŽãèŠãŠãã ããã
ããã«ç®ç«ã€ã®ã¶ã®ã¶ã®ãã£ãŒãã å®éã«ã¯ããã¹ãŠã®ããŒãã«ã®ããã©ãŒãã³ã¹ã¯ãçŸåšã®è² è·ä¿æ°ãã€ãŸãå
å¡«ã®çšåºŠã«å¿ããŠç°ãªããŸãã 25ïŒ
ã®å Žåãæ€çŽ¢ã¯50ïŒ
ã®å Žåãããé«éã«ãªããŸããããŒãã«ããã£ã±ãã«ãªãã»ã©ãããã·ã¥ã®è¡çªãçºçããŸãã æ€çŽ¢ã®ã³ã¹ããäžæããããæç¹ã§ããŒãã«ãæºæ¯ã§ãããšå€æããåé
åžããæãæ¥ããããåã³æ€çŽ¢ãé«éã«ãªããŸãã
ããã¯ãåããŒãã«ã®ãã¥ãŒãã£ãµã€ã¯ã«ããããããããšæããã§ãã ãŸãã max_load_factor
ã0.5ã®å Žåã«äžã®ã°ã©ããååŸããã max_load_factor
å Žåã«äžã®ã°ã©ããååŸãããããšãããã«ããããŸãã åé¡ã¯ããã«çºçããŸãïŒäžã®ã°ã©ãã®ããŒãã«ã¯ãåãå€ïŒ0.5ïŒãæã€äžã®ã°ã©ããããé«éã§ããïŒ ã§ãããããéåžžã«ãããã 次ã«ããã®ç¶æ³ãããå®å
šã«æ€èšããŸãã ã°ã©ãã¯ãè¡šãåé
åžãããã°ããã§ããã£ã«ãã¡ã¯ã¿ãŒã0.5ããããã«è¶
ããå Žåãäžéšã®ã°ã©ãã®äžéšãã€ã³ãã¯ããã£ã«ãã¡ã¯ã¿ãŒã0.5ã«è¿ã¥ããšããäºå®ã«ãããåé
åžã®çŽåã®äžéšã®ã°ã©ãã®äžéšãã€ã³ããããã¯ããã«é«ãäœçœ®ã«ããããšã瀺ããŠããŸãã
ãŸããå·ŠåŽã§ã¯ããã¹ãŠã®ã°ã©ããæ¯èŒçå¹³åŠã§ããããšãããããŸãã ãã®çç±ã¯ãããŒãã«ãå®å
šã«ãã£ãã·ã¥ãããŠããããã§ãã ããŒã¿ãL3ãã£ãã·ã¥ã«åãŸããªããªã£ãå Žåã«ã®ã¿ãã°ã©ãã¯èããåå²ããŸãã ããã¯å€§ããªåé¡ã ãšæããŸãã ç§ã®æèŠã§ã¯ãã°ã©ãã®å³åŽã¯å·ŠåŽãããã¯ããã«æ£ç¢ºã«ç¶æ³ãåæ ããŠããŸããç®çã®ã¢ã€ãã ãæ¢ã«ãã£ãã·ã¥ã«ããå Žåã«ã®ã¿å·ŠåŽãšåæ§ã®çµæãåŸãããŸãã
ãã®ããããã£ãã·ã¥ã«ãªãããŒãã«ã®é床ã瀺ããã¹ããæãã€ããã L3ã«åãŸããªãã»ã©å€ãã®ããŒãã«ãäœæããæ€çŽ¢ããã¢ã€ãã ããšã«ç°ãªãããŒãã«ã䜿çšããŸããã å8ãã€ãã®32åã®èŠçŽ ãå«ãããŒãã«ã®é床ã枬å®ãããšããŸãã ç§ã®L3ãã£ãã·ã¥ã®ãµã€ãºã¯6 MBãªã®ã§ããã®ãããªããŒãã«ã®çŽ25,000ãåãŸããŸãã ãã£ãã·ã¥ã«ããŒãã«ããªãããšã確èªããããã«ã75,000åã®ããŒãžã³ã§ããŒãã«ãäœæããŸããã ãããŠãåæ€çŽ¢ã¯å¥ã
ã®ããŒãã«ã§å®è¡ãããŸããã

ããã€ãã®è¡ãæ
å ±äŸ¡å€ããªãããåé€ããŸããã boost::unordered_map
ãšstd::unordered_map
ã¯éåžžåãããã©ãŒãã³ã¹ã瀺ããå€ãé
ãsherwood_map
ããŒãã«ã¯èª°ãæ°ã«ããŸããã çŸåšã次ã®ãã®ããããŸãïŒ std::unordered_map
ããŒãã«åºã¥ãéåžžã®ã³ã³ãããšããŠã®std::unordered_map
ïŒããŒãããŒã¹ã®ã³ã³ããïŒã boost::multi_index
ã«åºã¥ãããŒãã«åºã¥ãã¯ã€ãã¯ã³ã³ããïŒ std::unordered_map
ã¯ããã»ã©éãã¯ãªãã¯ãã§ãïŒã google::dense_hash_map
çŽ æ©ããªãŒãã³ã¢ãã¬ã·ã³ã°ã³ã³ãããšããŠã®google::dense_hash_map
ãš2ã€ã®ããŒãžã§ã³ã®2ã€ã®çŽ¯ä¹ã«åºã¥ãæ°ããã³ã³ããã
æ°ãããã³ãããŒã¯ã§ã¯ãã°ã©ãã£ãã¯ã¹ã¯ããã«å€§ããå€åãå§ããŸããã æåã®ãã³ãããŒã¯ã®ã°ã©ãã«è¡šç€ºããããã¿ãŒã³ã¯ã10åã®èŠçŽ ããå§ãŸã2çªç®ã®ãã³ãããŒã¯ã®ã°ã©ãã®éåžžã«æ©ã段éã§é¡èã«ãªããŸããã å°è±¡çïŒãã¹ãŠã®ããŒãã«ã¯ãéåžžã«åºç¯å²ã®èŠçŽ æ°ã§å®å®ããããã©ãŒãã³ã¹ãçºæ®ããŸãã
æ€çŽ¢ã倱æããå Žåã®ã°ã©ããã€ãŸããããŒãã«ã«ãªãã¢ã€ãã ã®æ€çŽ¢ãèŠãŠã¿ãŸãããã

ã»ã¬ãŒã·ã§ã³ã¯ããã«é¡èã§ããã£ã«ãã¡ã¯ã¿ãŒãéèŠãªåœ¹å²ãæãããŸãã ããŒãã«ããã£ã±ãã«ãªãã»ã©ãã·ã¹ãã ã¯èŠçŽ ãæ¬ èœããŠãããšå€æããåã«å€ãã®èŠçŽ ãèŠãå¿
èŠããããŸãã ããããç§ã¯ããŒãã«ã®çµæãæ¬åœã«å¥œãã§ããã»ããã®æ°ãå¶éããããšã¯ããŸãããããã§ãã ç§ã®ããŒãã«ã¯ãä»ã®ããŒãã«ãããå®å®ããããã©ãŒãã³ã¹ã瀺ããŠããŸãã
ãããã®ã°ã©ãã¯ãç§ã®æ°ããããŒãã«ã倧ããªåé²ã§ããããšã確信ãããŸããã èµ€ãç·ã¯ã dense_hash_map: max_load_factor 0,5
ãšåãæ¹æ³ã§æ§æãããããŒãã«ã®åäœã瀺ãã2ã®ã¹ãä¹ã®ãµã€ãºã決å®ããéžæã«ããã dense_hash_map: max_load_factor 0,5
ãããã ãã§ããã·ã¥ãã¹ãããã«å
¥ããããšãã§ããŸãã å¯äžã®å€§ããªéãïŒç§ã®ããŒãã«ã¯ãåã¹ãããã®ã¹ãã¬ãŒãžïŒããã³ããã£ã³ã°ïŒã«äœåãªãã€ãã䜿çšããŸãã dense_hash_map
ã dense_hash_map
ãããå°ãå€ãã®ã¡ã¢ãªãæ¶è²»ããŸãã
åæã«ãçŽ æ°ã䜿çšããŠããŒãã«ã®ãµã€ãºã決å®ããå Žåã§ããããŒãã«ã®é床ã¯å£ããŸããã ããã«ã€ããŠè©³ãã説æããŸãããã
çŽ æ°ãŸãã¯2ã®ã¹ãä¹
ããŒãã«å
ã®ã¢ã€ãã ãèŠã€ããã«ã¯ã3ã€ã®é«äŸ¡ãªã¹ãããããããŸãã
- ããŒããã·ã¥ã
- ã¹ãããã«ããŒãé
眮ããŸãã
- ãã®ã¹ãããã®ã¡ã¢ãªãååŸããŸãã
ã¹ããŒãž1ã¯ãããŒãæŽæ°ã§ããå Žåãå®äŸ¡ã§ããå¯èœæ§ããããŸãsize_t
ã¹ããŒããã ãã§ãã ããããæååãªã©ã®ä»ã®ã¿ã€ãã®ããŒã§ã¯ãã¹ããŒãžã¯ããé«äŸ¡ã«ãªããŸãã
ã¹ããŒãž2ã¯ãã¢ãžã¥ãæŽæ°ã§ãã
ã¹ããŒãž3-ãã€ã³ã¿ãŒã®åç
§è§£é€ã std::unordered_map
å Žåstd::unordered_map
ããã¯è€æ°ã®ãã€ã³ã¿ãŒã®éåç
§ã§ãã
ããã·ã¥ãé
ãããªãå Žåã¯ãã¹ããŒãž3ãæãè²»çšããããããã§ãã ãã ãã1åã®æ€çŽ¢ã§ãã£ãã·ã¥ãã¹ããªãå Žåã2çªç®ã®æ®µéãæãè²»çšããããå¯èœæ§ãé«ããªããŸãã æŽæ°ã¢ãžã¥ãã¯ã匷åãªããŒããŠã§ã¢ã§ããã£ãããšåŠçãããŸãã Intelã«ãããš ãããã«ã¯80ã95ãµã€ã¯ã«ãå¿
èŠã§ãã
ããããæ¬åœã«é«éãªããã·ã¥ããŒãã«ãéåžž2ã®ã¹ãä¹ã䜿çšããŠé
åã®ãµã€ãºã決å®ããäž»ãªçç±ã§ãã ãªããªãã1ãµã€ã¯ã«ã§å®è¡ã§ããæäžäœããããåé€ããã ãã§ååã ããã§ãã
ãããã2ã®ã¹ãä¹ã«ã¯å€§ããªæ¬ ç¹ããããŸãã2ã®ã¹ãä¹ã䜿çšãããšãå€ãã®å
¥åãã¿ãŒã³ãå€æ°ã®ããã·ã¥è¡çªãåŒãèµ·ãããŸãã 2çªç®ã®ãã³ãããŒã¯ã®ã°ã©ãã次ã«ç€ºããŸãããä»åã¯ä¹±æ°ã䜿çšããŸããã§ããã

ã¯ããããã§ãïŒ google::dense_hash_map
ã¯æå±€åã«å
¥ããŸããã ãããè¡ãã«ã¯ã圌女ã«äžé£ã®æ°å[0ã1ã2ã...ãn-2ãn-1]ãé çªã«äžããã ãã§ååã§ããã ãããè¡ã£ãŠãããŒãã«ã«ãªãããŒãæ¢ããšãæ€çŽ¢ã¯éåžžã«é
ããªããŸãã ããŒãããã°ããã¹ãŠãããŸããããããã«åäœããŸãã ãã®å Žåãæåããæ€çŽ¢ãšå€±æããæ€çŽ¢ã®çç£æ§ã®å·®ã¯æ°ååã«éããå¯èœæ§ããããŸãã
2ã®ã¹ãä¹ã«ããåé¡ã®å¥ã®äŸïŒRustã®æšæºããã·ã¥ããŒãã«ã¯ãããããŒãã«ããå¥ã®ããŒãã«ã«ããŒãæ¿å
¥ãããšãã«2次çãªåäœã瀺ãå§ããŸããã ãããã£ãŠã2ã®çŽ¯ä¹ã䜿çšãããšãäžå¿«ãªé©ãã«ã€ãªããå¯èœæ§ããããŸãã
å¶ç¶ãç§ã®ããŒãã«ã¯ã»ããã®æ°ãå¶éããããšã§ãããã®åé¡ããã¹ãŠé¿ããŸããã äžå¿
èŠãªåé
åžãããããŸããã§ããã ããããããã¯ãç§ã®ããŒãã«ã2ã®çŽ¯ä¹ã䜿çšããããšã®å¯äœçšã«å¯ŸããŠç¡æµã§ããããšãæå³ããŸããã ããšãã°ãã©ããããããããã®ãããªããŒãã«ã«ãã€ã³ã¿ãŒãæ¿å
¥ãããšãäžéšã®ã¹ããããåžžã«ç©ºã§ãããšããäºå®ã«åºäŒããŸããã , 16- , -, reinterpret_casted size_t
. - . -.
, -, . : -. , . , , . ( ).
? , , , . , , 32 , 16- ( 16). : 0 16. 32 16, . , . , 37 , 16 37 .
? boost::multi_index
: (compile time constant). . , . . - , :
switch(prime_index) { case 0: return 0llu; case 1: return hash % 2llu; case 2: return hash % 3llu; case 3: return hash % 5llu; case 4: return hash % 7llu; case 5: return hash % 11llu; case 6: return hash % 13llu; case 7: return hash % 17llu; case 8: return hash % 23llu; case 9: return hash % 29llu; case 10: return hash % 37llu; case 11: return hash % 47llu; case 12: return hash % 59llu;
â . ããã¯ã©ãã§ããïŒ , . , , . , .
: , -, . , . , std::map
. , , . , .
. - , . ? , - -, , . - . , , dense_hash_map
, , , .
, . : , , , . . -, , . , - , , std::hash
-, (stateful), . , , , .
, , , - , . . typedef
hash_policy
-. , .
, typedef
-:
struct CustomHashFunction { size_t operator()(const YourStruct & foo) {
- hash_policy
ska::power_of_two_hash_policy
. flat_hash_map
. std::hash
, power_of_two_std_hash
, std::hash
, power_of_two_hash_policy
:
ska::flat_hash_map<K, V, ska::power_of_two_std_hash<K>> your_hash_map;
-, , .
. , . , N , . reserve()
:

, . , . , .
, , L3. , , , â .
google::dense_hash_map
, . , dense_hash_map
. . Robin Hood , « ». . , .
, , reserve()
:

, . , . , malloc (Linux gcc). , .
, - , reserve
. , , google::dense_hash_map
.
, . N . N:

, . 23 , dense_hash_map
â 20. .
: dense_hash_map
, «» (tombstone). , . «» (quadratic probing), google::dense_hash_map
: , . Robin Hood , : , . , . . «», . .
, «», . dense_hash_map
. , , : :

. -, , . . , : 1, 2, 3 4. «, , » : 1, 3, 1, 2, 4, 4, 4, 1, 2, 3, 3, 2. , , . . â . â , ( ). â , , , , . . ãªã©ãªã©ã
dense_hash_map
, . , â . 6 . , , . , 500 . . --, . , dense_hash_map
«», . dense_hash_map
:

, dense_hash_map
, «». . Robin Hood : , . , .
max_load_factor()
, std::unordered_map
boost::multi_index
max_load_factor, 1,0, google::dense_hash_map
0,5. max_load_factor
? , ( ), max_load_factor
0,5. .

, max_load_factor
0,5, , , . , , . , , - , max_load_factor
.
flat_hash_map
dense_hash_map
, . , dense_hash_map
, : L3, flat_hash_map
.
boost::multi_index
std::unordered_map
, max_load_factor
1,0, flat_hash_map
dense_hash_map
, max_load_factor
â 0,5. , flat- .
, , . , -, . , max_load_factor
. , , - . â . : .
(map from int to int). . â :

, . . , . , - . :

: , google::dense_hash_map
, boost::multi_index
. : dense_hash_map
, , , «». , , std::string(1, 0)
std::string(1, 255)
. , , , . .
, . , . , . :

, dense_hash_map
( ). .
. (map from int to int), 32- ? 1024- ? 12 ([, 32-, 1024-] Ã [, ] Ã [ , ]), , : , . : 1024- :

, 1024- multi_index
flat-. , , - prefetcher . , 1024 .
, : . flat- . max_load_factor
0,5, . : , , . , â . , (prefetch) .
(size of the type), . 32- :

, flat-, : , . , boost::multi_index
. , 1024- :

: flat- , , . .
: dense_hash_map
( ). , 32 - (default constructed value type). - â 1024 , 32 . , , .
dense_hash_map
. , , -, - , , .
, , , reserve()
. , , , reserve()
:

, - boost::multi_index
. dense_hash_map
, , , - , «» / . , , «» , 1024 ? , .
, : 16 385 . 16 384 . 1028 , , 16 , . , - . , , . , , : , clear_page_c_e
. , , clear_page_c_e
. - . , .
, . . , .
:

dense_hash_map
. , ( Ubuntu 16.04) , .
, . . reserve()
:

, , . , . : , , - , . - :

dense_hash_map
- . . , flat_hash_map_power_of_two
16 385 - clear_page_c_e
.
: - , , reserve()
. , .
. : 4, 32 1024 . 4- . 32 , . 1024 :

dense_hash_map
. : , no-op , dense_hash_map
«» /, , 1024 .
: flat_hash_map
. , , . , , flat_hash_map
, , 1028 .
, . :

1024 , .
â «, , » . 10 ., 10 . 10 . . - 32 :

flat_hash_map
dense_hash_map
. .

- dense_hash_map
. , . , reserve()
, . flat- , â . , unordered_map
- , , multi_index
. , multi_index
:

, , 1028 . , : . , , multi_index
:

. 32- - . - 1024 , , , , .
, , - . , . . : , , , . . , , :
- , .
- . .
- , , . flat-. flat- .
- , . - .
google::dense_hash_map
.boost::multi_index
â -. .- , - , , -, .
äŸå€
, , -, (equality function) . (move constructor) . , . , .
Github . Boost-. ska::flat_hash_map
ska::flat_hash_set
. , std::unordered_map
std::unordered_set
.
, . , ska::power_of_two_hash_policy.
, max_load_factor
0,5. 0,9. , . , 70 %, . , max_load_factor
, .
ãŸãšã
, -. . â . log2(n), O(log(n)) O(n). . Robin Hood .
- Boost- hash_map hash_set. !