Benjamin Sago / ogham / cairnrefinery / etc…

Technical notes Make fish start faster by avoiding ‘alias’

The traditional way to write your own shell functions and aliases is to include them in your .bashrc or .zshrc configuration files, and have bash or zsh evaluate the definitions on startup, making them available to your running shell.

The fish shell works differently, preferring that you put all your functions in a functions/ directory, with one file per function. The advantage of doing it this way is that fish can start much faster. Instead of having to evaluate shell script to define the user’s custom functions — regardless of whether they will be actually used in the shell session — it can simply look at the names of files in a folder, only evaluating the script the first time a function is invoked.

This difference meant that fish did not actually offer ‘alias’ functionality at first. It now does, with the alias command. However, because fish aliases are merely functions under the hood, defining many of them in your fish_config file can make your shell take a surprisingly long time to start, compared to having them as regular functions.

Benchmarking ‘function’ vs ‘alias’

Using a script, I defined one hundred simple functions of the form:

function print_1; echo 1; end
function print_2; echo 2; end
function print_3; echo 3; end
# etc.

And then, one hundred aliases of the form:

alias print_1 "echo 1"
alias print_2 "echo 2"
alias print_3 "echo 3"
# etc.

I then measured how long fish took to start up (using hyperfine) for using functions or aliases in fish_config or in separate files. The results are as follows, compared to the baseline measurement I took before adding either of those things:

0 ms10 ms20 ms30 ms40 ms50 ms60 ms70 msBaseline9.0 msFunctions(in config)9.6 msAliases(in config)61.2 msFunctions(in files)9.0 msAliases(in files)9.0 ms

Using aliases instead of functions had no impact, and definining functions directly in fish_config had a tiny impact, but defining aliases directly in fish_config had a massive impact.

So if you want to define many aliases in your fish configuration file, but you don’t want to make your shell slower to start up, you have two options:

  1. Replace your aliases with functions, and leave them in your fish_config file. This is best way to make your shell start faster if you’ve noticed it getting slow.
  2. Move your aliases into the fish functions/ directory, with one file per function. This will make your shell start faster than if you converted them into functions, but by such an insignificant margin it’s hardly worth it.