From 72a313d3922d109a4351a4dec15e903b2a70d0a3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Wed, 16 Mar 2022 17:33:07 +0100 Subject: [PATCH] Resolve sort predicate ahead of time * 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 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sort.c b/src/sort.c index 5aa121a419b..a2c3c4d8e5c 100644 --- a/src/sort.c +++ b/src/sort.c @@ -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); -- 2.39.5