Subject: [PATCH 0/4] Making fewer 'stat' calls during startup
From: Ludovic Courtès <[email-masked]>
To: [email-masked]
Cc: Ludovic Courtès <[email-masked]>
Date: Mon, 7 Dec 2020 16:21:59 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi Guix!

On Guix System, with 6 entries in $GUILE_LOAD_PATH (which should just
be 2 entries, one for /run/current-system and one for ~/.guix-profile),
I see this:

--8<---------------cut here---------------start------------->8---
$ strace -c -e stat,openat guix
guix: mankas komanda nomo
Provu 'guix --help' por pli da informo.
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 90.94    0.002207           0      2283      2057 stat
  9.06    0.000220           0       334       177 openat
------ ----------- ----------- --------- --------- ----------------
100.00    0.002427           0      2617      2234 total
--8<---------------cut here---------------end--------------->8---

This is a lot of ‘stat’ calls for nothing, 4 times more than when
GUILE_LOAD_PATH is unset:

--8<---------------cut here---------------start------------->8---
$ env -i $(type -P strace) -c -e stat,openat $(type -P guix)
guix: missing command name
Try `guix --help' for more information.
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 57.89    0.000187           0       495       272 stat
 42.11    0.000136           0       321       175 openat
------ ----------- ----------- --------- --------- ----------------
100.00    0.000323           0       816       447 total
--8<---------------cut here---------------end--------------->8---

This patch series takes a sledgehammer approach to always have as
few ‘stat’ calls as possible during startup.  After the change, I get:

--8<---------------cut here---------------start------------->8---
$ strace -e stat,openat -c /gnu/store/g9gylj723si8i2cp8ia57a7kr4i8b1m9-guix-20201207.14/bin/guix 
guix: mankas komanda nomo
Provu 'guix --help' por pli da informo.
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 60.53    0.000322           0       454       231 stat
 39.47    0.000210           0       334       177 openat
------ ----------- ----------- --------- --------- ----------------
100.00    0.000532           0       788       408 total
$ env -i $(type -P strace) -e stat,openat -c /gnu/store/g9gylj723si8i2cp8ia57a7kr4i8b1m9-guix-20201207.14/bin/guix 
guix: missing command name
Try `guix --help' for more information.
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 69.92    0.000272           0       442       219 stat
 30.08    0.000117           0       321       175 openat
------ ----------- ----------- --------- --------- ----------------
100.00    0.000389           0       763       394 total
--8<---------------cut here---------------end--------------->8---

What impact does it have on startup time?  Hard to tell.
On my 4-year old x86_64 laptop with an SSD, it seems to be negligible,
even on a cold cache.  I suspect things are different on spinning
disks and on NFS.

The semantic difference should be invisible to users: their modules
are still visible and usable in manifests, in ‘guix repl’, etc.; they
just cannot take precedence over modules from Guile and from the
channels.  For instance, one cannot define a (gnu packages base)
module or (ice-9 rdelim), drop it in $GUILE_LOAD_PATH, and have that
module picked up in lieu of the original one.  I think that’s a
reasonable tradeoff.

Thoughts?

Ludo’.

Ludovic Courtès (4):
  build: 'script/guix' uses our own 'guile' executable.
  self: Move Guile early in the module search path.
  guix: 'guile' executable ignores GUILE_LOAD_PATH during startup.
  self: Remove the empty string from '%load-extensions'.

 Makefile.am                             |  1 +
 gnu/packages/aux-files/guile-launcher.c | 46 +++++++++++++++++++++++--
 guix/self.scm                           | 26 +++++++++-----
 scripts/guix.in                         |  2 +-
 4 files changed, 63 insertions(+), 12 deletions(-)

-- 
2.29.2