GNU bug report logs - #78637
30.1.90; Calling setopt during init loads cus-start over and over

Previous Next

Package: emacs;

Reported by: Aaron Zeng <azeng <at> janestreet.com>

Date: Thu, 29 May 2025 20:58:02 UTC

Severity: normal

Found in version 30.1.90

Full log


Message #8 received at 78637 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Aaron Zeng <azeng <at> janestreet.com>
Cc: 78637 <at> debbugs.gnu.org, app-emacs-dev <at> janestreet.com
Subject: Re: bug#78637: 30.1.90;
 Calling setopt during init loads cus-start over and over
Date: Fri, 30 May 2025 10:24:08 +0300
> Cc: app-emacs-dev <at> janestreet.com
> Date: Thu, 29 May 2025 16:57:22 -0400
> From:  Aaron Zeng via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> While trying to improve Emacs startup time at my site, I noticed that
> cus-start was being loaded repeatedly, each time setopt was called.
> It seems that, when called during site-start or loading the user's
> init file, setopt (which eventually calls custom-load-symbol) requires
> cus-start, ignoring errors---and loading cus-start at that moment does
> indeed error.
> 
> As a result of this ignored error, cus-start is loaded from scratch
> each time (require 'cus-start) is evaluated.  This adds something like
> 12ms of startup time to Emacs batch commands at my site, since we have
> about 25 setopt calls in site-start, and each one takes an extra 500us
> or so.
> 
> I performed a quick experiment, with:
> 
>     emacs -Q --batch --init-directory=example-init --user ""
> 
> where example-init/init.el contains just:
> 
>     (dotimes (_ 25)
>       (setopt make-backup-files nil))
> 
> Running the above command under hyperfine shows that the runtime is
> about 82ms on my machine.
> 
> Prepending this code to example-init/init.el:
> 
>     (ignore-errors
>       (require 'cus-start))
>     (push 'cus-start features)
> 
> drops the runtime of the command to 75ms.  (I believe this experiment
> might underestimate the true impact of repeatedly loading cus-start
> due to caching effects.)

I don't understand: cus-start is preloaded (see lisp/loadup.el), so
"(require 'cus-start)" should be (almost) a no-op.  Do you have any
evidence that cus-start.el is indeed being loaded under this recipe?
If so, can you present that evidence?  (And no, the fact that startup
time goes down doesn't mean that loading cus-start is the reason, it
could be something else.)

> I believe this can be fixed with the following patch.  On my machine,
> this patch reduces the runtime of the original init file to 75ms and
> causes the prepended code to make no difference to the runtime.
> 
> diff --git a/lisp/cus-start.el b/lisp/cus-start.el
> index 91cc6e22152..e82e97e87ca 100644
> --- a/lisp/cus-start.el
> +++ b/lisp/cus-start.el
> @@ -934,7 +934,7 @@ minibuffer-prompt-properties--setter
>        ;; This is used by describe-variable.
>        (if version (put symbol 'custom-version version))
>        ;; Don't re-add to custom-delayed-init-variables post-startup.
> -      (unless after-init-time
> +      (when (listp custom-delayed-init-variables)
>  	;; Note this is the _only_ initialize property we handle.
>  	(if (eq (cadr (memq :initialize rest)) #'custom-initialize-delay)
>  	    ;; These vars are defined early and should hence be initialized

I think this patch changes behavior, so it is not TRT.  But before we
discuss how to fix the problem, let's be sure we understand the
problem and its reason(s).




This bug report was last modified 13 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.