From 2b8a920a7ca8ec49de4f7a2d1a7dcbbce57cf26b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 24 Mar 2024 16:40:51 +0100 Subject: [PATCH] AK: Don't blindly use SipHash as default hash function Although it has some interesting properties, SipHash is brutally slow compared to our previous hash function. Since its introduction, it has been highly visible in every profile of doing anything interesting with LibJS or LibWeb. By switching back, we gain a 10x speedup for 32-bit hashes, and "only" a 3x speedup for 64-bit hashes. This comes out to roughly 1.10x faster HashTable insertion, and roughly 2.25x faster HashTable lookup. Hashing is no longer at the top of profiles and everything runs measurably faster. For security-sensitive hash tables with user-controlled inputs, we can opt into SipHash selectively on a case-by-case basis. The vast majority of our uses don't fit that description though. --- AK/Traits.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/AK/Traits.h b/AK/Traits.h index b6f35573820..f098f50e32e 100644 --- a/AK/Traits.h +++ b/AK/Traits.h @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace AK { @@ -41,7 +40,10 @@ struct Traits : public DefaultTraits { static constexpr bool is_trivially_serializable() { return true; } static unsigned hash(T value) { - return standard_sip_hash(static_cast(value)); + if constexpr (sizeof(T) < 8) + return int_hash(value); + else + return u64_hash(value); } }; @@ -52,14 +54,17 @@ struct Traits : public DefaultTraits { static constexpr bool is_trivially_serializable() { return true; } static unsigned hash(T value) { - return standard_sip_hash(bit_cast(static_cast(value))); + if constexpr (sizeof(T) < 8) + return int_hash(bit_cast(value)); + else + return u64_hash(bit_cast(value)); } }; #endif template requires(IsPointer && !Detail::IsPointerOfType) struct Traits : public DefaultTraits { - static unsigned hash(T p) { return standard_sip_hash(bit_cast(p)); } + static unsigned hash(T p) { return ptr_hash(bit_cast(p)); } static constexpr bool is_trivial() { return true; } };