From: Stefan Monnier Date: Sat, 12 Dec 2020 15:59:50 +0000 (-0500) Subject: * src/fns.c (hash_string): Tweak the code further X-Git-Tag: emacs-28.0.90~4748 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=8eee54d23adfbd723805851e3904ec21294788ed;p=emacs.git * src/fns.c (hash_string): Tweak the code further Merge the two main branches; remove the `max` test and thus reduce the "most steps" to 8 as written --- diff --git a/src/fns.c b/src/fns.c index f77092972ab..646c3ed0834 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4525,40 +4525,36 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p) EMACS_UINT hash_string (char const *ptr, ptrdiff_t len) { - if (len < 16) + EMACS_UINT const *p = (EMACS_UINT const *) ptr; + EMACS_UINT const *end = (EMACS_UINT const *) (ptr + len); + EMACS_UINT hash = len; + /* At most 8 steps. We could reuse SXHASH_MAX_LEN, of course, + * but dividing by 8 is cheaper. */ + ptrdiff_t step = 1 + ((end - p) >> 3); + + /* Beware: `end` might be unaligned, so `p < end` is not always the same + * as `p <= end - 1`. */ + while (p <= end - 1) { - char const *p = ptr; - char const *end = p + len; - EMACS_UINT hash = len; - - while (p < end) - { - unsigned char c = *p++; - hash = sxhash_combine (hash, c); - } - - return hash; + EMACS_UINT c = *p; + p += step; + hash = sxhash_combine (hash, c); } - else - { - EMACS_UINT const *p = (EMACS_UINT const *) ptr; - EMACS_UINT const *end = (EMACS_UINT const *) (ptr + len); - EMACS_UINT hash = len; - /* At most 8 steps. We could reuse SXHASH_MAX_LEN, of course, - * but dividing by 8 is cheaper. */ - ptrdiff_t step = max (1, (end - p) >> 3); - - /* Beware: `end` might be unaligned, so `p < end` is not always the same - * as `p <= end - 1`. */ - while (p <= end - 1) + if (p < end) + { /* A few last bytes remain (smaller than an EMACS_UINT). */ + /* FIXME: We could do this without a loop, but it'd require + endian-dependent code :-( */ + char const *p1 = (char const *)p; + char const *end1 = (char const *)end; + do { - EMACS_UINT c = *p; - p += step; + unsigned char c = *p1++; hash = sxhash_combine (hash, c); } - - return hash; + while (p1 < end1); } + + return hash; } /* Return a hash for string PTR which has length LEN. The hash