Homebrew / homebrew-command-not-found

🔍 Ubuntu’s command-not-found equivalent for Homebrew on macOS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

command-not-found causes VERY long zsh startup times

vegerot opened this issue · comments

This is my zshrc

start=`gdate +%s.%N`
export ZSH="$HOME/.oh-my-zsh"
fpath=(/usr/local/share/zsh-completions /usr/local/share/zsh-completions/conda-zsh-completion $fpath)
source $ZSH/oh-my-zsh.sh

end=`gdate +%s.%N`
runtime=$( echo "$end - $start"|bc -l )
echo "$runtime seconds"

when I open zsh the output is always around .118130000 seconds

Now when I try adding command-not found:

start=`gdate +%s.%N`
export ZSH="$HOME/.oh-my-zsh"
fpath=(/usr/local/share/zsh-completions /usr/local/share/zsh-completions/conda-zsh-completion $fpath)
if brew command command-not-found-init > /dev/null; then
  eval "$(brew command-not-found-init)";
fi
source $ZSH/oh-my-zsh.sh

end=`gdate +%s.%N`
runtime=$( echo "$end - $start"|bc -l )
echo "$runtime seconds"

Now when I open zsh, the output is around 2.358168000 seconds!

Clearly, this is unacceptable. What can be done to speed this up?

Can you confirm time brew command ls or time brew help give normal run times?

It’s also very slow on my machine but it’s due to Homebrew itself, as every brew invocation appears to have a ~1.8s overhead.

@bfontaine as you said, there is an overhead from brew.

/usr/local/Homebrew/Library/Homebrew/cmd/list.rb
brew command ls  0.64s user 0.62s system 94% cpu 1.340 total

However, the startup time increase in unacceptable for my (or anybody's) bashrc. Would it be possible to run this asynchronously, or to cache the results, or something to make this more acceptable? I mean, this script doesn't even NEED to do anything during the shell startup, only when you run commands. Would it be possible to just have brew command-not-found-init define from shell functions that only get executed when needed? This would save tons of time.

Of course, no matter how little brew command-not-found-init does, if any brew command has that startup overhead, it seems to be an intractable problem. Unless, of course, we could cache the functions, and update the instructions to something like

if [ -f "/usr/local/bin/cellar/..."]; then
  source "/usr/local/bin/cellar/...";
fi

That file just containing a bunch of definitions and/or cached results. This would bypass having to run brew. Again, if it added just a bit of time I wouldn't complain. But I think MOST people would think adding an extra SECOND to their shell startup for some basic functionality would be a dealbreaker.

Yep, I agree on the overhead. I feel like it’s recent as I don’t remember having any slowness issue when I originally created the command.

In the end, all the Ruby command does is check your shell and dump the appropriate handler -- handler.sh for Bash/Zsh or handler.fish for Fish.

That shell part defines the command-not-found hook and registers it for the current session. It can’t be asynchronous because it must run in the current shell.

I’m not on a Mac right now but something like this should feel instantaneous:

HB_CNF_HANDER="$(brew --prefix)/Homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh"
if [ -f "$HB_CNF_HANDER" ]; then
  source "$HB_CNF_HANDER";
fi

brew --prefix returns before Homebrew starts loading Ruby, so it doesn’t suffer from its performance issues.

commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

So should I/someone make a PR fixing this?

Yes, that would be great!

commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

I've been seeing slow startup times myself as well, in my case with Bash's .bash_profile. Is there a planned PR for this?

@andrewarchi I might work on a PR if I have some free time

commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.