Nameless
Nameless copied to clipboard
[Fix #24] Run nameless--after-hack-local-variables just once
The suggested use of nameless is
(add-hook 'emacs-lisp-mode-hook #'nameless-mode)
Prior to this change, running nameless in this way would cause
nameless--after-hack-local-variables
to get run twice on opening a
file: once when running run-hooks
, and once again when running
hack-local-variables-hook
. This operation is slow on large files,
and running it twice is even slower.
You might think that it would suffice to simply remove the direct call
to nameless--after-hack-local-variables
in nameless-mode
, but then
nameless-mode
would fail to "toggle" when run interactively.
Instead, we just check whether the function is being called
interatively, "toggling" if it is, then add the function to
hack-local-variables-hook
. There are probably more elegant ways to
do this, but the basic idea is probably the same in all cases.
To time this change, I used
(defun nameless-benchmark ()
(interactive)
(benchmark 5 '(progn
(find-file "~/emacs/lisp/org/org.el")
(kill-buffer "org.el"))))
(org.el
is just shy of 25_000 lines.)
Here are the results of running that twice on master and twice with this change (times recorded on my crappy little Thinkpad):
- Before
Elapsed time: 107.945053s (34.001933s in 213 GCs)
Elapsed time: 107.498577s (33.706725s in 215 GCs)
- After
Elapsed time: 56.372983s (18.334976s in 115 GCs)
Elapsed time: 56.753919s (18.720507s in 116 GCs)
The time is cut in half. This is not surprising, as the expensive operation is being executed half as often.
As I mentioned in that issue, my understanding of hooks and local variables is hazy, so I might be missing something subtle. That said, this seems to work locally.
Thanks for this!
The only negative side-effect I can see is that if someone has some code that calls this mode non-interactively it will stop working with this change.
Ideally, instead of checking for (called-interactively-p 'any)
, we would have a way of checking if local variables have already been loaded in this file. Do you know if there's a way of checking for that?
I don't know. There must be something. But whatever the exact solution, I think it will look something like this: adding the hack-locals hook if called from a hook, and changing the display immediately if called directly.