straight.el icon indicating copy to clipboard operation
straight.el copied to clipboard

Package require route cacher component

Open errge opened this issue 9 months ago • 2 comments

If I strace my emacs setup, there is this part in the middle:

openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/outli/windmove.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000012>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/outli/windmove.so.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/outli/windmove.elc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/outli/windmove.elc.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/outli/windmove.el", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/outli/windmove.el.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/request/windmove.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/request/windmove.so.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/request/windmove.elc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/request/windmove.elc.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000012>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/request/windmove.el", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000018>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/request/windmove.el.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000010>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/popup/windmove.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000013>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/popup/windmove.so.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000010>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/popup/windmove.elc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/popup/windmove.elc.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/popup/windmove.el", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/popup/windmove.el.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dash/windmove.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dash/windmove.so.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dash/windmove.elc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dash/windmove.elc.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dash/windmove.el", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dash/windmove.el.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/s/windmove.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/s/windmove.so.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/s/windmove.elc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/s/windmove.elc.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/s/windmove.el", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/s/windmove.el.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dumb-jump/windmove.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dumb-jump/windmove.so.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000010>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dumb-jump/windmove.elc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dumb-jump/windmove.elc.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dumb-jump/windmove.el", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/dumb-jump/windmove.el.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/keypress-multi-event/windmove.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/keypress-multi-event/windmove.so.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/keypress-multi-event/windmove.elc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/keypress-multi-event/windmove.elc.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/keypress-multi-event/windmove.el", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/keypress-multi-event/windmove.el.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/home-end/windmove.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/home-end/windmove.so.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/home-end/windmove.elc", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/home-end/windmove.elc.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/home-end/windmove.el", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/home-end/windmove.el.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000008>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/seq/windmove.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000009>
openat(AT_FDCWD, "/home/errge/.emacs.d/straight/build/seq/windmove.so.gz", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000021>

This is of course working as intended, the counter of load-path * load-suffixes * load-file-rep-suffixes scales like that, it's just math. If someone were to represent this as a bug, it would be more like a bug in GNU Emacs than in straight.

But I just wanted to float the idea, because we already have the build-cache architecture and everything in place to solve this, to add the following to straight: on each require save the found path into the build cache in a new hash table, and reuse that later if possible (or try the normal require, if the cached info proves to be outdated).

It would reduce the number of syscall round trips in the most happy (99%) case of restart emacs + no changes to installation to 1 from 100.

Strictly speaking this could be a feature that is built-in to Emacs or built-in a separate library, but I'm floating it as a straight.el feature, as mentioned, because we already have the infra.

I might work on this if I find the time, but I wanted to ask for input before I get started, to make sure I don't do stuff that is not upstreamable or not liked.

errge avatar Apr 02 '25 19:04 errge

For some quick gains I added this to my early-init:

(set 'load-file-rep-suffixes '(""))
(require 'finder-inf) ;; GNU emacs bug reported: autogenerated finder-inf never byte-compiled
(set 'load-suffixes '(".elc"))

The startup time with -nw went from 0.08 to 0.055, and we still have to go through the load-path, we just save on the suffixes.

This avenue is definitely worthwhile to pursue in some form inside or outside of straight.

errge avatar Apr 02 '25 19:04 errge

That's a pretty neat trick with the custom load-suffixes, and I agree that using a hash table as an optimization for load-path is reasonable. I am open to having straight.el provide an optional advice for require (or similar functions) that would perform this optimization based on data available from previous init runs. The same for customizing load-suffixes - it should be a pretty reasonable approach given that straight.el guarantees all packages are byte-compiled before being loaded. Perhaps the two can be combined into an optional minor mode that can be enabled at the start of init if the user desires.

raxod502 avatar Apr 03 '25 20:04 raxod502