]> git.eshelyaron.com Git - emacs.git/commitdiff
* src/fns.c (hash_string): Tweak the code further
authorStefan Monnier <monnier@iro.umontreal.ca>
Sat, 12 Dec 2020 15:59:50 +0000 (10:59 -0500)
committerStefan Monnier <monnier@iro.umontreal.ca>
Sat, 12 Dec 2020 15:59:50 +0000 (10:59 -0500)
Merge the two main branches; remove the `max` test and thus reduce
the "most steps" to 8 as written

src/fns.c

index f77092972ab71718c45fec3434e9f562e4420f17..646c3ed08344e7c3edd1e6b00b14a25c0df78081 100644 (file)
--- 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