From 509185edfe85924016bd6558c0d641f81e5e8c3d Mon Sep 17 00:00:00 2001 From: Bodigrim Date: Thu, 28 Mar 2024 21:15:03 +0000 Subject: [PATCH] Rework benchmarks --- README.md | 28 +++++++++++++++++++- bench/Bench.hs | 67 +++++++++++++++++------------------------------- xxhash-ffi.cabal | 3 --- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index badc8cb..7eeb848 100644 --- a/README.md +++ b/README.md @@ -5,4 +5,30 @@ xxhash-ffi [![Stackage Nightly](http://stackage.org/package/xxhash-ffi/badge/nightly)](http://stackage.org/nightly/package/xxhash-ffi) [![Stackage LTS](http://stackage.org/package/xxhash-ffi/badge/lts)](http://stackage.org/lts/package/xxhash-ffi) -Fastest Haskell FFI bindings to the xxHash library. The C implementation is directly taken from [xxHash](https://github.com/Cyan4973/xxHash). +Haskell indings and high-level helpers for [xxHash](https://xxhash.com) family +of extremely fast non-cryptographic hash functions. + +Benchmarks against `hashable-1.4.3.0` on `aarch64`: + +``` +10B + Data.Digest.XXHash.FFI.XXH3: + 10.2 ns ± 208 ps + Data.Hashable: + 12.1 ns ± 404 ps +1kB + Data.Digest.XXHash.FFI.XXH3: + 71.7 ns ± 1.8 ns + Data.Hashable: + 1.14 μs ± 27 ns +4kB + Data.Digest.XXHash.FFI.XXH3: + 289 ns ± 7.0 ns + Data.Hashable: + 4.71 μs ± 187 ns +1MB + Data.Digest.XXHash.FFI.XXH3: + 175 μs ± 6.9 μs + Data.Hashable: + 2.87 ms ± 108 μs +``` diff --git a/bench/Bench.hs b/bench/Bench.hs index 1ac065e..0ebeac7 100644 --- a/bench/Bench.hs +++ b/bench/Bench.hs @@ -8,9 +8,6 @@ import Prelude hiding (words) import qualified Data.ByteString as B import qualified Data.Digest.Adler32 as Adler32 import qualified Data.Digest.CRC32 as CRC32 -#ifdef MIN_VERSION_xxhash -import qualified Data.Digest.XXHash as XXHash -#endif import qualified Data.Digest.XXHash.FFI as FFI #ifdef MIN_VERSION_hashable import qualified Data.Hashable as Hashable @@ -25,59 +22,43 @@ main = do defaultMain [ bgroup "10B" - [ bench "Data.Digest.XXHash.FFI (32) (c)" $ nf (FFI.xxh32 bs10b) 0 - , bench "Data.Digest.XXHash.FFI (64) (c)" $ nf (FFI.xxh64 bs10b) 0 -#ifdef MIN_VERSION_xxhash - , bench "xxhash (c)" $ nf XXHash.c_xxHash' bs10b - , bench "Data.Digest.XXHash (haskell)" $ nf XXHash.xxHash' bs10b -#endif - , bench "Data.Digest.adler32 (c, zlib)" $ nf Adler32.adler32 bs10b - , bench "Data.Digest.crc32 (c, zlib)" $ nf CRC32.crc32 bs10b + [ bench "Data.Digest.XXHash.FFI.xxh32" $ nf (FFI.xxh32 bs10b) 0 + , bench "Data.Digest.XXHash.FFI.xxh64" $ nf (FFI.xxh64 bs10b) 0 + , bench "Data.Digest.Adler32" $ nf Adler32.adler32 bs10b + , bench "Data.Digest.CRC32" $ nf CRC32.crc32 bs10b #ifdef MIN_VERSION_hashable - , bench "Data.Digest.XXHash (c, XXH3)" $ nf Hashable.hash (FFI.XXH3 bs10b) - , bench "Data.Hashable (c, FNV?)" $ nf Hashable.hash bs10b + , bench "Data.Digest.XXHash.FFI.XXH3" $ nf Hashable.hash (FFI.XXH3 bs10b) + , bench "Data.Hashable" $ nf Hashable.hash bs10b #endif ] , bgroup "1kB" - [ bench "Data.Digest.XXHash.FFI (32) (c)" $ nf (FFI.xxh32 bs1k) 0 - , bench "Data.Digest.XXHash.FFI (64) (c)" $ nf (FFI.xxh64 bs1k) 0 -#ifdef MIN_VERSION_xxhash - , bench "xxhash (c)" $ nf XXHash.c_xxHash' bs1k - , bench "Data.Digest.XXHash (haskell)" $ nf XXHash.xxHash' bs1k -#endif - , bench "Data.Digest.adler32 (c, zlib)" $ nf Adler32.adler32 bs1k - , bench "Data.Digest.crc32 (c, zlib)" $ nf CRC32.crc32 bs1k + [ bench "Data.Digest.XXHash.FFI.xxh32" $ nf (FFI.xxh32 bs1k) 0 + , bench "Data.Digest.XXHash.FFI.xxh64" $ nf (FFI.xxh64 bs1k) 0 + , bench "Data.Digest.Adler32" $ nf Adler32.adler32 bs1k + , bench "Data.Digest.CRC32" $ nf CRC32.crc32 bs1k #ifdef MIN_VERSION_hashable - , bench "Data.Digest.XXHash (c, XXH3)" $ nf Hashable.hash (FFI.XXH3 bs1k) - , bench "Data.Hashable (c, FNV?)" $ nf Hashable.hash bs1k + , bench "Data.Digest.XXHash.FFI.XXH3" $ nf Hashable.hash (FFI.XXH3 bs1k) + , bench "Data.Hashable" $ nf Hashable.hash bs1k #endif ] , bgroup "4kB" - [ bench "Data.Digest.XXHash.FFI (32) (c)" $ nf (FFI.xxh32 bs4k) 0 - , bench "Data.Digest.XXHash.FFI (64) (c)" $ nf (FFI.xxh64 bs4k) 0 -#ifdef MIN_VERSION_xxhash - , bench "xxhash (c)" $ nf XXHash.c_xxHash' bs4k - , bench "Data.Digest.XXHash (haskell)" $ nf XXHash.xxHash' bs4k -#endif - , bench "Data.Digest.adler32 (c, zlib)" $ nf Adler32.adler32 bs4k - , bench "Data.Digest.crc32 (c, zlib)" $ nf CRC32.crc32 bs4k + [ bench "Data.Digest.XXHash.FFI.xxh32" $ nf (FFI.xxh32 bs4k) 0 + , bench "Data.Digest.XXHash.FFI.xxh64" $ nf (FFI.xxh64 bs4k) 0 + , bench "Data.Digest.Adler32" $ nf Adler32.adler32 bs4k + , bench "Data.Digest.CRC32" $ nf CRC32.crc32 bs4k #ifdef MIN_VERSION_hashable - , bench "Data.Digest.XXHash (c, XXH3)" $ nf Hashable.hash (FFI.XXH3 bs4k) - , bench "Data.Hashable (c, FNV?)" $ nf Hashable.hash bs4k + , bench "Data.Digest.XXHash.FFI.XXH3" $ nf Hashable.hash (FFI.XXH3 bs4k) + , bench "Data.Hashable" $ nf Hashable.hash bs4k #endif ] , bgroup "1MB" - [ bench "Data.Digest.XXHash.FFI (32) (c)" $ nf (FFI.xxh32 med) 0 - , bench "Data.Digest.XXHash.FFI (64) (c)" $ nf (FFI.xxh64 med) 0 -#ifdef MIN_VERSION_xxhash - , bench "xxhash (c)" $ nf XXHash.c_xxHash' med - , bench "Data.Digest.XXHash (haskell)" $ nf XXHash.xxHash' med -#endif - , bench "Data.Digest.adler32 (c, zlib)" $ nf Adler32.adler32 med - , bench "Data.Digest.crc32 (c, zlib)" $ nf CRC32.crc32 med + [ bench "Data.Digest.XXHash.FFI.xxh32" $ nf (FFI.xxh32 med) 0 + , bench "Data.Digest.XXHash.FFI.xxh64" $ nf (FFI.xxh64 med) 0 + , bench "Data.Digest.Adler32" $ nf Adler32.adler32 med + , bench "Data.Digest.CRC32" $ nf CRC32.crc32 med #ifdef MIN_VERSION_hashable - , bench "Data.Digest.XXHash (c, XXH3)" $ nf Hashable.hash (FFI.XXH3 med) - , bench "Data.Hashable (c, FNV?)" $ nf Hashable.hash med + , bench "Data.Digest.XXHash.FFI.XXH3" $ nf Hashable.hash (FFI.XXH3 med) + , bench "Data.Hashable" $ nf Hashable.hash med #endif ] ] diff --git a/xxhash-ffi.cabal b/xxhash-ffi.cabal index b5fc325..fab1198 100644 --- a/xxhash-ffi.cabal +++ b/xxhash-ffi.cabal @@ -96,8 +96,5 @@ benchmark xxhash-ffi-bench digest, murmur-hash - if impl(ghc <9.2) - build-depends: xxhash - if impl(ghc <9.10) build-depends: hashable