From 51d94bbb14f069103697c5e0cccd11d653b09b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20=F0=9F=91=A8=F0=9F=8F=BD=E2=80=8D=F0=9F=92=BB=20Copl?= =?UTF-8?q?an?= Date: Wed, 11 Sep 2024 13:32:52 -0700 Subject: [PATCH] feat: add benchmark for displaying all programs in PATH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This is the first regression we've seen for `fd` vs. `find`. ```sh $ PATH="/opt/homebrew/Cellar/findutils/4.10.0/libexec/gnubin/:$PATH" ./warm-cache-exe-paths.sh Benchmark 1: FIND_PROG=find FIND_ARGS='-maxdepth 1 -executable -type f,l -printf %f\n' get_programs_in_path Time (mean ± σ): 142.0 ms ± 6.0 ms [User: 32.7 ms, System: 72.0 ms] Range (min … max): 129.7 ms … 154.6 ms 20 runs Benchmark 2: FIND_PROG='fd .' FIND_ARGS='--hidden --max-depth=1 --type=executable --follow --format {/} ' get_programs_in_path Time (mean ± σ): 272.1 ms ± 6.0 ms [User: 88.8 ms, System: 142.1 ms] Range (min … max): 258.2 ms … 279.9 ms 10 runs Summary FIND_PROG=find FIND_ARGS='-maxdepth 1 -executable -type f,l -printf %f\n' get_programs_in_path ran 1.92 ± 0.09 times faster than FIND_PROG='fd .' FIND_ARGS='--hidden --max-depth=1 --type=executable --follow --format {/} ' get_programs_in_path Both fd and find found the same 2943 results ``` --- warm-cache-exe-paths.sh | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100755 warm-cache-exe-paths.sh diff --git a/warm-cache-exe-paths.sh b/warm-cache-exe-paths.sh new file mode 100755 index 0000000..a303a2e --- /dev/null +++ b/warm-cache-exe-paths.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +source "prelude.sh" + +# extracted from https://github.com/vegerot/dotfiles/blob/a9a50230d808572173d3eeec057739d0fe8d4470/bin/fzf-menu by @vegerot +get_programs_in_path() { + local find_prog + local find_args + if [[ -n "${FIND_PROG:-}" ]]; then + find_prog=$FIND_PROG + find_args=${FIND_ARGS:-} + elif find / -maxdepth 0 -executable &>/dev/null || command -v gfind &>/dev/null; then + # GNU find + find_prog="$(command -v gfind || echo find) -L" + find_args="-maxdepth 1 -executable -type f,l -printf %f\n" + elif command -v fd > /dev/null; then + find_prog="fd ." + find_args="--hidden --max-depth=1 --type=executable --follow --format {/}" + else + # BSD find + find_prog="find" + find_args="-maxdepth 1 -perm +111 -type f,l -exec basename {} ;" + fi + + local pathDeduped=$(printf '%s\n' $PATH | tr ':' '\n' | uniq ) + for p in $pathDeduped; do + $find_prog $p $find_args 2>/dev/null || true + done \ + | awk '!x[$0]++' + # awk removes duplicates without sorting. Thanks https://stackoverflow.com/a/11532197/6100005 \ + } +export -f get_programs_in_path + + +COMMAND_FIND="FIND_PROG='find -L' FIND_ARGS='-maxdepth 1 -executable -type f,l -printf %f\n' get_programs_in_path" +COMMAND_FD="FIND_PROG='fd .' FIND_ARGS='--hidden --max-depth=1 --type=executable --follow --format {/} ' get_programs_in_path" + +hyperfine --shell=bash --warmup "$WARMUP_COUNT" \ + "$COMMAND_FIND" \ + "$COMMAND_FD" \ + --export-markdown results-warm-cache-no-pattern.md +check_for_differences "false" "$COMMAND_FIND" "$COMMAND_FD"