Nameless icon indicating copy to clipboard operation
Nameless copied to clipboard

[Fix #24] Run nameless--after-hack-local-variables just once

Open nickdrozd opened this issue 6 years ago • 3 comments

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.

nickdrozd avatar Jul 23 '18 01:07 nickdrozd

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.

nickdrozd avatar Jul 23 '18 01:07 nickdrozd

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?

Malabarba avatar Jul 25 '18 00:07 Malabarba

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.

nickdrozd avatar Jul 30 '18 20:07 nickdrozd