Boot speed.
0. Do as little as necessary. and put off stuff not necessary to start X into xinit (you really only
_need_ to mount /proc, /sys, /dev and the rootfs)
1. run as much as possible in parallel &
a. if there are no prerequisites to running a command/function and it is not a prerequisite to others, then you can just add a & to the end.
b. if there are prerequisites involved, use the builtin $! variable to store the PID(s) (technically job IDs) of a parallel command(s), so that you can use the wait command to ensure the prerequisite calls are complete.
Code: Select all
wait_cmd(){ #wait for job ID(s) in $ to complete, then run rest of arguments as a command
wait $1
shift
$@
}
foo &
foo_JID=$!
bar &
bar_JID=$!
#Note the quotes around and spaces between job IDs
wait_cmd "$foo_JID $bar_JID" baz
This method can be even more effective than systemd's pathetic parallel-ization methods
2. avoid unnecessary sleep(s) or at least unnecessarily long ones
a. use an appropriate check or wait command instead where possible with short sleeps in a loop rather than just using really long sleeps
Code: Select all
#example
#sleep 5 && jwm
#wait for the X server to establish the unix socket instead
COUNT=99
while
[ ! -S /tmp/.X11-unix/X0 ] || [ $COUNT > 0 ]
do
sleep .1
COUNT=$((COUNT-1))
done
[ $COUNT > 0 ] && jwm || echo X timed out
3. use busybox (or toybox) instead of GNU utils, they are smaller, so they load faster and the shells are about 4x faster than bash
4. when operating on strings, variables or even small files(< ~100 lines) use the shell's substring manipulation and other builtins instead of external utilities like awk, grep, sed, tr, which
see
http://www.murga-linux.com/puppy/viewtopic.php?t=70238
5. minimize unnecessary files in your initramfs/rootfs...
One or two large files compress better (and load faster) than many smaller files - its better to include all the functions in the init script or at least a single function header than to use a bunch of smaller ones. This speeds up load times in the initramfs because it compresses better and reduces seek and load times in both the initramfs and rootfs (especially if the rootfs is on a slower or fragmented disk drive).
If a kernel module is needed in the init, chances are it should be builtin.
Similarly shared libraries add additional bloat and load time (for multiple reasons), a static busybox built against musl or uclibc can significantly cut down load times. The popular rant against static builds in favor of shared libraries by Ulrich Drepper is backed up by metrics based on glibc (which he maintained) which is horribly suited for static builds (a simple static hello world is over 400kb)
see
https://sta.li/faq
6. use tools like bootchartd, strace and lsof to measure the files used and times spent in various sections and the order, you can use this to "readahead" files that will be used and to order the filesystem so that files are in sequential order
7. use kernel parameters
libahci.ignore_sss=1 #spin up disks in parallel instead of series
quiet #eliminates superfluous messages from the console
loglevel=3 #or less... only log the most critical issues the lower the number, the fewer log messages
#probably more
8. don't write unnecessary stuff to the console ... or if you must, write as much as possible at once (for example, use a single success/fail message that handles multiple items instead of doing them one ata time). printf is useful for this