Search code examples
profilingfish

How can I profile the Fish shell init?


Is there a way to see what is taking how much time each thing is taking when I start a new shell (e.g. some function that is running and etc).

Is it possible?

The only thing I can think of to help is doing things like:

~
λ time fish -i -c exit

________________________________________________________
Executed in  142.29 millis    fish           external
   usr time   76.19 millis   68.00 micros   76.12 millis
   sys time   61.52 millis  469.00 micros   61.05 millis

And then trying to remove things out and measuring again... not ideal though.


Solution

  • Fish has a built-in profiling function.

    Since fish 3.2 it has --profile to profile just the commands you gave and --profile-startup to profile the startup time, before that --profile would profile both together.

    Use like

    fish --profile-startup /tmp/fish.profile -i -c exit
    

    This will create a file called "/tmp/fish.profile" looking like

    Time    Sum Command
    415 2505    > builtin source /usr/share/fish/config.fish
    15  15  -> set -g IFS \n\ \t
    6   6   -> set -qg __fish_added_user_paths
    4   4   -> set -g __fish_added_user_paths
    1   4   -> if not set -q __fish_initialized...
    3   3   --> not set -q __fish_initialized
    3   3   -> function __fish_default_command_not_found_handler...
    4   72  -> if status --is-interactive...
    

    The first column is the time a command itself took (in microseconds, so 1000000 is 1s), the second the time it and all parts of it (including function calls and command substitutions) took, the third is the command plus an indicator of how deep in the callstack this is.

    To see the biggest time investments sort -nk2 /tmp/fish.profile is useful - this sorts by the second column so it'll show the big ticket items last (i.e. closest to the next prompt).

    Note that this also shows fish's internal startup - that set -g IFS for instance is a fish internal thing, but that tends to be quick so it won't be prominent.