shepmaster / twox-hash

A Rust implementation of the XXHash algorithm.
MIT License
358 stars 41 forks source link

xxh3::Hash64 is much slower than XxHash64 #94

Open stepancheg opened 1 year ago

stepancheg commented 1 year ago

Test program:

https://gist.github.com/stepancheg/6b0b493821f162eb5126dbbf2a070887

hashes strings of various lengths and outputs hash duration. Output is not reliable, but relative numbers should be.

On my Apple M1 laptop and twox-hash 1.6.3 the output is:

   0:  fnv=  15   xx=  12  xxh3=  55   def=  12   nop=  15
   1:  fnv=  10   xx=  11  xxh3=  30   def=  10   nop=  10
   2:  fnv=  10   xx=  11  xxh3=  29   def=  10   nop=  10
   3:  fnv=  10   xx=  12  xxh3=  30   def=  10   nop=  10
   4:  fnv=  10   xx=  14  xxh3=  30   def=  10   nop=  10
   5:  fnv=  10   xx=  12  xxh3=  30   def=  10   nop=  10
   6:  fnv=  10   xx=  12  xxh3=  30   def=  10   nop=  10
   7:  fnv=  10   xx=  13  xxh3=  31   def=  11   nop=  10
   8:  fnv=  10   xx=  11  xxh3=  33   def=  10   nop=  10
  10:  fnv=  10   xx=  12  xxh3=  30   def=  11   nop=  10
  12:  fnv=  11   xx=  12  xxh3=  30   def=  11   nop=  10
  14:  fnv=  11   xx=  13  xxh3=  31   def=  11   nop=  10
  16:  fnv=  11   xx=  12  xxh3=  31   def=  11   nop=  10
  20:  fnv=  11   xx=  12  xxh3=  33   def=  11   nop=  10
  24:  fnv=  13   xx=  12  xxh3=  32   def=  11   nop=  10
  28:  fnv=  16   xx=  12  xxh3=  33   def=  11   nop=  10
  32:  fnv=  20   xx=  12  xxh3=  31   def=  11   nop=  10
  40:  fnv=  27   xx=  12  xxh3=  32   def=  11   nop=  10
  48:  fnv=  37   xx=  13  xxh3=  32   def=  12   nop=  10
  56:  fnv=  48   xx=  12  xxh3=  32   def=  13   nop=  10
  64:  fnv=  58   xx=  12  xxh3=  33   def=  13   nop=  10
  80:  fnv=  76   xx=  12  xxh3=  33   def=  17   nop=  10
  96:  fnv=  95   xx=  12  xxh3=  33   def=  19   nop=  10
 112:  fnv= 117   xx=  13  xxh3=  34   def=  23   nop=  10
 128:  fnv= 135   xx=  12  xxh3=  35   def=  25   nop=  10
 160:  fnv= 176   xx=  13  xxh3=  55   def=  34   nop=  10
 192:  fnv= 216   xx=  13  xxh3=  57   def=  44   nop=  10
 224:  fnv= 257   xx=  15  xxh3=  59   def=  52   nop=  10
 256:  fnv= 298   xx=  16  xxh3=  75   def=  62   nop=  10
 320:  fnv= 378   xx=  18  xxh3=  78   def=  80   nop=  10
 384:  fnv= 459   xx=  21  xxh3=  85   def=  99   nop=  10
 448:  fnv= 541   xx=  25  xxh3=  96   def= 119   nop=  10
 512:  fnv= 624   xx=  29  xxh3=  95   def= 138   nop=  10
 640:  fnv= 788   xx=  38  xxh3= 117   def= 176   nop=  10
 768:  fnv= 950   xx=  46  xxh3= 120   def= 215   nop=  10
 896:  fnv=1112   xx=  53  xxh3= 141   def= 251   nop=  10
1024:  fnv=1272   xx=  62  xxh3= 165   def= 288   nop=  10

which means XXH3 implementation is about three times slower than XXHash64.

Documentation of xxh3 page links to the website https://cyan4973.github.io/xxHash/ which says "The latest variant, XXH3, offers improved performance across the board, especially on small data" and posts a table describing the results, while my measurements show the opposite.

If this works as expected, please close the issue.

stepancheg commented 1 year ago

Also I did another benchmark, comparing implementations, the results for strings of length 0..50 is:

DefaultHasher:             avg= 9.365ns std=0.042ns
FnvHasher:                 avg=12.658ns std=0.104ns
twox_hash::XxHash64:       avg=10.186ns std=0.079ns
twox_hash::xxh3::Hash64:   avg=38.926ns std=0.145ns
xxhash_rust::xxh64::Xxh64: avg= 9.738ns std=0.032ns
xxhash_rust::xxh3::Xxh3:   avg=10.413ns std=0.052ns

This benchmark is a bit harder to publish as standlone example, but anyway, seems like something is broken in twox-hash XXH3 implementation.