]> git.eshelyaron.com Git - emacs.git/commitdiff
Resolve sort predicate ahead of time
authorMattias Engdegård <mattiase@acm.org>
Wed, 16 Mar 2022 16:33:07 +0000 (17:33 +0100)
committerMattias Engdegård <mattiase@acm.org>
Thu, 17 Mar 2022 09:35:57 +0000 (10:35 +0100)
* src/sort.c (tim_sort): If the sort predicate is a symbol, find the
corresponding function before starting the sort.  This is especially
beneficial if the predicate was an alias (`string<`, for example).

src/sort.c

index 5aa121a419bc13245a78638211ae68250376d631..a2c3c4d8e5c6eb00473311672baec8d595446c8f 100644 (file)
@@ -913,12 +913,24 @@ reverse_vector (Lisp_Object *s, const ptrdiff_t n)
 void
 tim_sort (Lisp_Object predicate, Lisp_Object *seq, const ptrdiff_t length)
 {
+  if (SYMBOLP (predicate))
+    {
+      /* Attempt to resolve the function as far as possible ahead of time,
+        to avoid having to do it for each call.  */
+      Lisp_Object fun = XSYMBOL (fun)->u.s.function;
+      if (SYMBOLP (fun))
+       /* Function was an alias; use slow-path resolution.  */
+       fun = indirect_function (fun);
+      /* Don't resolve to an autoload spec; that would be very slow.  */
+      if (!NILP (fun) && !(CONSP (fun) && EQ (XCAR (fun), Qautoload)))
+       predicate = fun;
+    }
+
   merge_state ms;
   Lisp_Object *lo = seq;
 
   merge_init (&ms, length, lo, predicate);
 
-
   /* March over the array once, left to right, finding natural runs,
      and extending short natural runs to minrun elements.  */
   const ptrdiff_t minrun = merge_compute_minrun (length);