Speed up Tap#cask_files_by_name

This is most noticeable when you have a large local tap and it ends
up taking a nontrivial percentage of the overall run time for simple
commands like `brew info gimp`. The improvement here is to just
create paths later on in the loop which copies what we already do
for formulae.

See b1ddb05

```console
$ hyperfine --parameter-list branch master,speed-up-cask-files-by-name --warmup 5 --setup 'git switch {branch}' 'brew info gimp'
Benchmark 1: brew info gimp (branch = master)
  Time (mean ± σ):      2.737 s ±  0.010 s    [User: 1.958 s, System: 0.732 s]
  Range (min … max):    2.720 s …  2.748 s    10 runs

Benchmark 2: brew info gimp (branch = speed-up-cask-files-by-name)
  Time (mean ± σ):      2.597 s ±  0.017 s    [User: 1.828 s, System: 0.724 s]
  Range (min … max):    2.577 s …  2.624 s    10 runs

Summary
  brew info gimp (branch = speed-up-cask-files-by-name) ran
    1.05 ± 0.01 times faster than brew info gimp (branch = master)
```
This commit is contained in:
apainintheneck 2024-08-21 23:31:43 -07:00
parent 019fc519da
commit fff4e0a8f0

View File

@ -1427,12 +1427,16 @@ class CoreCaskTap < AbstractCoreTap
def cask_files_by_name
return super if Homebrew::EnvConfig.no_install_from_api?
@cask_files_by_name ||= Homebrew::API::Cask.all_casks.each_with_object({}) do |item, hash|
name, cask_hash = item
# If there's more than one item with the same path: use the longer one to prioritise more specific results.
existing_path = hash[name]
new_path = path/cask_hash["ruby_source_path"]
hash[name] = new_path if existing_path.nil? || existing_path.to_s.length < new_path.to_s.length
@cask_files_by_name ||= begin
tap_path = path.to_s
Homebrew::API::Cask.all_casks.each_with_object({}) do |item, hash|
name, cask_hash = item
# If there's more than one item with the same path: use the longer one to prioritise more specific results.
existing_path = hash[name]
# Pathname equivalent is slow in a tight loop
new_path = File.join(tap_path, cask_hash.fetch("ruby_source_path"))
hash[name] = Pathname(new_path) if existing_path.nil? || existing_path.to_s.length < new_path.length
end
end
end