From bca569ae535e4fb7a38f9ec9514e667fc15a29d2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 21 Nov 2022 23:19:42 -0700 Subject: [PATCH] [array] Speed up hash() for byte arrays --- src/hb-array.hh | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index fbc98e7c7..562f03cdf 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -424,17 +424,41 @@ inline bool hb_array_t::operator == (const hb_array_t -inline uint32_t hb_array_t::hash () const { +inline uint32_t hb_array_t::hash () const +{ uint32_t current = 0; - for (unsigned int i = 0; i < this->length; i++) + unsigned i = 0; + +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) + struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; + for (; i + 4 <= this->length; i += 4) + current = current * 31 + (uint32_t) ((((packed_uint32_t *) &this->arrayZ[i])->v) * 2654435761u); +#endif + + for (; i < this->length; i++) current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u); return current; } + template <> -inline uint32_t hb_array_t::hash () const { +inline uint32_t hb_array_t::hash () const +{ uint32_t current = 0; - for (unsigned int i = 0; i < this->length; i++) + unsigned i = 0; + +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) + struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; + for (; i + 4 <= this->length; i += 4) + current = current * 31 + (uint32_t) ((((packed_uint32_t *) &this->arrayZ[i])->v) * 2654435761u); +#endif + + for (; i < this->length; i++) current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u); return current; }