emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 8eee54d: * src/fns.c (hash_string): Tweak the code further


From: Stefan Monnier
Subject: master 8eee54d: * src/fns.c (hash_string): Tweak the code further
Date: Sat, 12 Dec 2020 10:59:57 -0500 (EST)

branch: master
commit 8eee54d23adfbd723805851e3904ec21294788ed
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    * 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
---
 src/fns.c | 52 ++++++++++++++++++++++++----------------------------
 1 file changed, 24 insertions(+), 28 deletions(-)

diff --git a/src/fns.c b/src/fns.c
index f770929..646c3ed 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]