Speed up brew tap for no arguments

This provides a >3x speedup for `brew tap` with no arguments (i.e., when
listing taps). It also makes the completion significantly faster.

    $ hyperfine --warmup=3 --setup 'git checkout {branch}' --parameter-list branch master,brew-tap-speedup 'brew tap'
    Benchmark 1: brew tap (branch = master)
      Time (mean ± σ):      1.405 s ±  0.080 s    [User: 0.561 s, System: 0.238 s]
      Range (min … max):    1.332 s …  1.549 s    10 runs

    Benchmark 2: brew tap (branch = brew-tap-speedup)
      Time (mean ± σ):     404.1 ms ± 124.8 ms    [User: 107.9 ms, System: 200.7 ms]
      Range (min … max):   308.8 ms … 693.7 ms    10 runs

    Summary
      brew tap (branch = brew-tap-speedup) ran
        3.48 ± 1.09 times faster than brew tap (branch = master)
This commit is contained in:
Ruoyu Zhong 2024-09-25 01:50:43 +08:00
parent 5697a2a7e1
commit 369fd3dcaf
No known key found for this signature in database
2 changed files with 46 additions and 0 deletions

View File

@ -172,6 +172,11 @@ case "$@" in
source "${HOMEBREW_LIBRARY}/Homebrew/list.sh" source "${HOMEBREW_LIBRARY}/Homebrew/list.sh"
homebrew-list "$@" && exit 0 homebrew-list "$@" && exit 0
;; ;;
# falls back to cmd/tap.rb on a non-zero return
tap*)
source "${HOMEBREW_LIBRARY}/Homebrew/tap.sh"
homebrew-tap "$@" && exit 0
;;
# falls back to cmd/help.rb on a non-zero return # falls back to cmd/help.rb on a non-zero return
help | --help | -h | --usage | "-?" | "") help | --help | -h | --usage | "-?" | "")
homebrew-help "$@" && exit 0 homebrew-help "$@" && exit 0

41
Library/Homebrew/tap.sh Normal file
View File

@ -0,0 +1,41 @@
# Does the quickest output of brew tap possible for no arguments.
# HOMEBREW_LIBRARY is set by bin/brew
# shellcheck disable=SC2154
normalise_tap_name() {
local dir="$1"
local user
local repo
user="$(echo "${dir%%/*}" | tr '[:upper:]' '[:lower:]')"
repo="$(echo "${dir#*/}" | tr '[:upper:]' '[:lower:]')"
repo="${repo#@(home|linux)brew-}"
echo "${user}/${repo}"
}
homebrew-tap() {
case "$1" in
# check we actually have tap and not e.g. tapsomething
tap) ;;
tap*) return 1 ;;
*) ;;
esac
# Named args are handled by the Ruby code.
if [[ "$#" -gt 1 ]]
then
return 1
fi
local taplib="${HOMEBREW_LIBRARY}/Taps"
(
shopt -s extglob
for dir in "${taplib}"/*/*
do
[[ -d "${dir}" ]] || continue
dir="${dir#"${taplib}"/}"
normalise_tap_name "${dir}"
done | sort
)
}