]> git.eshelyaron.com Git - emacs.git/commitdiff
Speed up sxhash-equal-including-properties
authorMattias Engdegård <mattiase@acm.org>
Sun, 14 Jan 2024 11:33:12 +0000 (12:33 +0100)
committerMattias Engdegård <mattiase@acm.org>
Sun, 14 Jan 2024 13:17:41 +0000 (14:17 +0100)
This function now no longer conses at all.  Previously, it constructed
a list structure of all string intervals for the sole purpose of
hashing.

* src/fns.c (hash_interval): New.
(Fsxhash_equal_including_properties):
Use it instead of collect_interval.

src/fns.c

index f7c36aacea68184b0701c9c6503ed35085853926..07bb5115b6cfc8a1fa0feaa88ee77d2c6853cef9 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -5240,6 +5240,17 @@ sxhash_obj (Lisp_Object obj, int depth)
     }
 }
 
+static void
+hash_interval (INTERVAL interval, void *arg)
+{
+  EMACS_UINT *phash = arg;
+  EMACS_UINT hash = *phash;
+  hash = sxhash_combine (hash, interval->position);
+  hash = sxhash_combine (hash, LENGTH (interval));
+  hash = sxhash_combine (hash, sxhash_obj (interval->plist, 0));
+  *phash = hash;
+}
+
 static void
 collect_interval (INTERVAL interval, void *arg)
 {
@@ -5310,14 +5321,9 @@ Hash codes are not guaranteed to be preserved across Emacs sessions.  */)
 {
   if (STRINGP (obj))
     {
-      /* FIXME: This is very wasteful.  We needn't cons at all.  */
-      Lisp_Object collector = Qnil;
-      traverse_intervals (string_intervals (obj), 0, collect_interval,
-                         &collector);
-      return
-       make_ufixnum (
-         SXHASH_REDUCE (sxhash_combine (sxhash (obj),
-                                        sxhash (collector))));
+      EMACS_UINT hash = 0;
+      traverse_intervals (string_intervals (obj), 0, hash_interval, &hash);
+      return make_ufixnum (SXHASH_REDUCE (sxhash_combine (sxhash (obj), hash)));
     }
 
   return hash_hash_to_fixnum (hashfn_equal (obj, NULL));