Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

brew --prefix is slow #2938

Closed
kevinburke opened this issue Jul 24, 2017 · 6 comments
Closed

brew --prefix is slow #2938

kevinburke opened this issue Jul 24, 2017 · 6 comments

Comments

@kevinburke
Copy link
Contributor

kevinburke commented Jul 24, 2017

I write code that supports a lot of other developers, and try to provide a seamless installation experience. To provide portable installation instructions that work with Homebrew installations on every user's machine, I need to find the Homebrew root directory using brew --prefix.

However, that's really slow; running time brew --prefix ten times on a 2015 Macbook Pro with 16GB RAM yielded results between 184ms and 347ms (it sped up as I ran it more often, though the uncached time is also important). This makes it infeasible to put at e.g. the top of a Makefile, or to use the output from brew --prefix as part of a Make target.

Is there a way we can speed it up? 95% of the time I feel like the answer is /usr/local; can we optimize for that case? Can we store the answer in a file somewhere and check that before doing expensive work? (I can build caching myself/for the users I support but it would be a little more cumbersome than building it into Homebrew).

@ilovezfs
Copy link
Contributor

maybe use dirname $(dirname $(which brew))?

@MikeMcQuaid
Copy link
Member

This has been optimised pretty heavily already. I'm not seeing it ever take more than 0.03s here which seems more than fast enough (particularly if you cache the value in an environment variable). If there's a way of making it dramatically faster without altering behaviour: we'll accept a pull request.

@kevinburke
Copy link
Contributor Author

kevinburke commented Jul 24, 2017 via email

@kevinburke
Copy link
Contributor Author

I put set -x at the top of bin/brew, then piped it to ts '[%Y-%m-%d %H:%M:%.S]', which prints timestamps for every output line. Here were the slow parts:

$ time brew --prefix 2>&1 | tsms
[2017-07-24 21:14:25.943493] ++ quiet_cd /usr/local/bin/
[2017-07-24 21:14:25.943908] ++ cd /usr/local/bin/
[2017-07-24 21:14:25.943947] ++ pwd -P
[2017-07-24 21:14:25.943973] + BREW_FILE_DIRECTORY=/usr/local/bin
[2017-07-24 21:14:25.943996] + HOMEBREW_BREW_FILE=/usr/local/bin/brew
[2017-07-24 21:14:25.944017] + HOMEBREW_PREFIX=/usr/local
[2017-07-24 21:14:25.944038] + [[ -z /usr/local ]]
[2017-07-24 21:14:25.944059] + [[ /usr/local = \/\u\s\r\/\l\o\c\a\l\/\b\i\n\/\b\r\e\w ]]
[2017-07-24 21:14:25.944080] + HOMEBREW_REPOSITORY=/usr/local
[2017-07-24 21:14:25.944099] + [[ -L /usr/local/bin/brew ]]
[2017-07-24 21:14:25.944118] ++ symlink_target_directory /usr/local/bin/brew /usr/local/bin
[2017-07-24 21:14:25.944138] +++ readlink /usr/local/bin/brew
[2017-07-24 21:14:25.944157] ++ local target=/usr/local/Homebrew/bin/brew
[2017-07-24 21:14:25.944177] +++ dirname /usr/local/Homebrew/bin/brew
[2017-07-24 21:14:25.944197] ++ local target_dirname=/usr/local/Homebrew/bin
[2017-07-24 21:14:25.944259] ++ local directory=/usr/local/bin
[2017-07-24 21:14:25.944288] ++ quiet_cd /usr/local/bin
[2017-07-24 21:14:25.944309] ++ cd /usr/local/bin
[2017-07-24 21:14:25.944327] ++ quiet_cd /usr/local/Homebrew/bin
[2017-07-24 21:14:25.944345] ++ cd /usr/local/Homebrew/bin
[2017-07-24 21:14:25.944362] ++ pwd -P
[2017-07-24 21:14:25.944379] + BREW_FILE_DIRECTORY=/usr/local/Homebrew/bin
[2017-07-24 21:14:25.944397] + HOMEBREW_REPOSITORY=/usr/local/Homebrew
[2017-07-24 21:14:25.944414] + [[ -L /usr/local/bin/brew ]]
[2017-07-24 21:14:25.944431] ++ symlink_target_directory /usr/local/bin/brew /usr/local/bin
[2017-07-24 21:14:25.944448] +++ readlink /usr/local/bin/brew
[2017-07-24 21:14:25.944466] ++ local target=/usr/local/Homebrew/bin/brew
[2017-07-24 21:14:25.944483] +++ dirname /usr/local/Homebrew/bin/brew
[2017-07-24 21:14:25.944501] ++ local target_dirname=/usr/local/Homebrew/bin
[2017-07-24 21:14:25.944518] ++ local directory=/usr/local/bin
[2017-07-24 21:14:25.944536] ++ quiet_cd /usr/local/bin
[2017-07-24 21:14:25.944553] ++ cd /usr/local/bin
[2017-07-24 21:14:25.944570] ++ quiet_cd /usr/local/Homebrew/bin
[2017-07-24 21:14:25.944587] ++ cd /usr/local/Homebrew/bin
[2017-07-24 21:14:25.944604] ++ pwd -P
[2017-07-24 21:14:25.944621] + USR_LOCAL_BREW_FILE_DIRECTORY=/usr/local/Homebrew/bin
[2017-07-24 21:14:25.945247] + USR_LOCAL_HOMEBREW_REPOSITORY=/usr/local/Homebrew
[2017-07-24 21:14:25.945294] + [[ /usr/local/Homebrew = \/\u\s\r\/\l\o\c\a\l\/\H\o\m\e\b\r\e\w ]]
[2017-07-24 21:14:25.945317] + HOMEBREW_PREFIX=/usr/local
[2017-07-24 21:14:25.945339] + HOMEBREW_LIBRARY=/usr/local/Homebrew/Library
[2017-07-24 21:14:25.945362] + for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY BROWSER EDITOR GIT PATH VISUAL
[2017-07-24 21:14:25.945384] + [[ -z '' ]]
[2017-07-24 21:14:25.945404] + continue
[2017-07-24 21:14:25.945423] + for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY BROWSER EDITOR GIT PATH VISUAL
[2017-07-24 21:14:25.945442] + [[ -z '' ]]
[2017-07-24 21:14:25.945461] + continue
[2017-07-24 21:14:25.945480] + for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY BROWSER EDITOR GIT PATH VISUAL
[2017-07-24 21:14:25.945499] + [[ -z '' ]]
[2017-07-24 21:14:25.945519] + continue
[2017-07-24 21:14:25.945538] + for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY BROWSER EDITOR GIT PATH VISUAL
[2017-07-24 21:14:25.946955] + [[ -z '' ]]
[2017-07-24 21:14:25.947020] + continue
[2017-07-24 21:14:25.947051] + for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY BROWSER EDITOR GIT PATH VISUAL
[2017-07-24 21:14:25.947075] + [[ -z '' ]]
[2017-07-24 21:14:25.947100] + continue
[2017-07-24 21:14:25.947127] + for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY BROWSER EDITOR GIT PATH VISUAL
[2017-07-24 21:14:25.947152] + [[ -z /usr/local/bin/nvim ]]
[2017-07-24 21:14:25.947177] + VAR_NEW=HOMEBREW_EDITOR
[2017-07-24 21:14:25.947203] + [[ -n '' ]]
[2017-07-24 21:14:25.947222] + export HOMEBREW_EDITOR=/usr/local/bin/nvim
[2017-07-24 21:14:25.947243] + HOMEBREW_EDITOR=/usr/local/bin/nvim
[2017-07-24 21:14:25.947262] + for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY BROWSER EDITOR GIT PATH VISUAL
[2017-07-24 21:14:25.947282] + [[ -z '' ]]
[2017-07-24 21:14:25.947437] + continue
[2017-07-24 21:14:25.947475] + for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY BROWSER EDITOR GIT PATH VISUAL
[2017-07-24 21:14:25.947500] + [[ -z /Users/kevin/local/share/nvm/versions/node/v4.4.6/bin:/Users/kevin/.rbenv/shims:/Users/kevin/.pyenv/shims:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/kevin/bin:/Users/kevin/local/bin:/Users/kevin/src/github.com/jkbrzt/httpie/venv/bin:/Users/kevin/src/github.com/rg3/youtube-dl/venv/bin:/Users/kevin/go/bin:/Users/kevin/.cargo/bin:/Users/kevin/src/github.com/jwilm/alacritty/target/release:/Users/kevin/.yarn/bin:/Users/kevin/.config/yarn/global/node_modules/.bin:/usr/local/sbin ]]
[2017-07-24 21:14:25.947528] + VAR_NEW=HOMEBREW_PATH
[2017-07-24 21:14:25.947549] + [[ -n '' ]]
[2017-07-24 21:14:25.947571] + export HOMEBREW_PATH=/Users/kevin/local/share/nvm/versions/node/v4.4.6/bin:/Users/kevin/.rbenv/shims:/Users/kevin/.pyenv/shims:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/kevin/bin:/Users/kevin/local/bin:/Users/kevin/src/github.com/jkbrzt/httpie/venv/bin:/Users/kevin/src/github.com/rg3/youtube-dl/venv/bin:/Users/kevin/go/bin:/Users/kevin/.cargo/bin:/Users/kevin/src/github.com/jwilm/alacritty/target/release:/Users/kevin/.yarn/bin:/Users/kevin/.config/yarn/global/node_modules/.bin:/usr/local/sbin
[2017-07-24 21:14:25.947720] + HOMEBREW_PATH=/Users/kevin/local/share/nvm/versions/node/v4.4.6/bin:/Users/kevin/.rbenv/shims:/Users/kevin/.pyenv/shims:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/kevin/bin:/Users/kevin/local/bin:/Users/kevin/src/github.com/jkbrzt/httpie/venv/bin:/Users/kevin/src/github.com/rg3/youtube-dl/venv/bin:/Users/kevin/go/bin:/Users/kevin/.cargo/bin:/Users/kevin/src/github.com/jwilm/alacritty/target/release:/Users/kevin/.yarn/bin:/Users/kevin/.config/yarn/global/node_modules/.bin:/usr/local/sbin
[2017-07-24 21:14:25.947749] + for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY BROWSER EDITOR GIT PATH VISUAL
[2017-07-24 21:14:25.947815] + [[ -z '' ]]
[2017-07-24 21:14:25.947837] + continue
[2017-07-24 21:14:25.947856] + [[ -n '' ]]
[2017-07-24 21:14:25.947874] + source /usr/local/Homebrew/Library/Homebrew/brew.sh
[2017-07-24 21:14:25.947892] +++ git -C /usr/local/Homebrew describe --tags --dirty --abbrev=7
[2017-07-24 21:14:26.006781] ++ HOMEBREW_VERSION=1.2.4-99-g9747bc3-dirty
[2017-07-24 21:14:26.006858] ++ HOMEBREW_USER_AGENT_VERSION=1.2.4-99-g9747bc3-dirty
[2017-07-24 21:14:26.006888] ++ [[ -z 1.2.4-99-g9747bc3-dirty ]]
[2017-07-24 21:14:26.006911] ++ export HOMEBREW_COMMAND_DEPTH=1
[2017-07-24 21:14:26.006930] ++ HOMEBREW_COMMAND_DEPTH=1
[2017-07-24 21:14:26.008035] +++ locale charmap
[2017-07-24 21:14:26.025621] ++ [[ UTF-8 != \U\T\F\-\8 ]]
[2017-07-24 21:14:26.025749] ++ [[ -d /usr/local/Homebrew/Cellar ]]
[2017-07-24 21:14:26.025820] ++ HOMEBREW_CELLAR=/usr/local/Cellar
[2017-07-24 21:14:26.026212] ++ case "$*" in
[2017-07-24 21:14:26.026354] ++ echo /usr/local
[2017-07-24 21:14:26.026414] /usr/local
[2017-07-24 21:14:26.026454] ++ exit 0
brew --prefix 2>&1  0.05s user 0.06s system 60% cpu 0.181 total
tsms  0.05s user 0.01s system 35% cpu 0.166 total

I timed git -C /usr/local/Homebrew describe --tags --dirty --abbrev=7 on its own, it takes about 100ms.

@kevinburke
Copy link
Contributor Author

If I am reading brew --prefix correctly it seems like the output of git describe is not used by anything before the case statement, so we could get a performance improvement by putting at least one branch of the case statement before git describe.

@MikeMcQuaid
Copy link
Member

If I am reading brew --prefix correctly it seems like the output of git describe is not used by anything before the case statement, so we could get a performance improvement by putting at least one branch of the case statement before git describe.

👍 to a PR for that.

@Homebrew Homebrew locked as resolved and limited conversation to collaborators Feb 27, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants