emacs-diffs
[Top][All Lists]
Advanced

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

master be0f2de: * src/fns.c (hash_string): Speed up on large strings


From: Stefan Monnier
Subject: master be0f2de: * src/fns.c (hash_string): Speed up on large strings
Date: Tue, 8 Dec 2020 18:08:59 -0500 (EST)

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

    * src/fns.c (hash_string): Speed up on large strings
---
 src/fns.c | 41 ++++++++++++++++++++++++++++++++---------
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/src/fns.c b/src/fns.c
index e4c9acc..23d24ef 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -18,6 +18,7 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
+#include <stdio.h>
 #include <config.h>
 
 #include <stdlib.h>
@@ -4525,18 +4526,40 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool 
remove_entries_p)
 EMACS_UINT
 hash_string (char const *ptr, ptrdiff_t len)
 {
-  char const *p = ptr;
-  char const *end = p + len;
-  unsigned char c;
-  EMACS_UINT hash = 0;
-
-  while (p != end)
+  if (len < 16)
     {
-      c = *p++;
-      hash = sxhash_combine (hash, c);
+      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;
     }
+  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)
+        {
+          EMACS_UINT c = *p;
+          p += step;
+          hash = sxhash_combine (hash, c);
+        }
 
-  return hash;
+      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]