I theorize that find outperforms for/test.  Below are two shell scripts:
if you run the first one it will let you know the results of two runs.
The second one is a modified dmenu_run that uses find.  I'd appreciate
it if people would run the first one and mail the results to me.  I'll
let the list know what the results are.

Here are my results:

    $ bin/fstest
    === find_binaries 1

    real    0m0.037s
    user    0m0.005s
    sys     0m0.013s
    === find_binaries 2

    real    0m0.024s
    user    0m0.003s
    sys     0m0.015s
    === shell_binaries 1

    real    0m5.099s
    user    0m0.469s
    sys     0m0.185s
    === shell_binaries 2

    real    0m0.476s
    user    0m0.401s
    sys     0m0.059s

On my system, the find version is 137 times faster before the OS has
cached the directories, and 19 times faster when directories are cached.
This is in part due to lots of symlinks pointing outside my path, but
mostly because find is more efficient.

-----8<----- findtest -----8<-----
#! /bin/sh

SPATH=$(IFS=:; for dir in $PATH; do echo "$dir"; done)

shell_binaries () {
    for dir in $SPATH; do
        for file in $dir/*; do
            test -x "$file" && echo ${file##*/}
        done
    done > /dev/null
}

find_binaries () {
    find $SPATH -maxdepth 1 \( -type f -o -type l \) -perm +111 -printf "%f\n" 
&> /dev/null
}

echo "=== find_binaries 1"
time find_binaries
echo "=== find_binaries 2"
time find_binaries

echo "=== shell_binaries 1"
time shell_binaries
echo "=== shell_binaries 2"
time shell_binaries
-----8<-----


-----8<----- dmenu_run -----8<-----
#! /bin/sh

binaries() {
    SPATH=$(IFS=:; for dir in $PATH; do echo "$dir"; done)
    find $SPATH -maxdepth 1 \( -type f -o -type l \) -perm +111 -printf "%f\n" 
2> /dev/null
}

exec $(binaries | sort | uniq | dmenu "$@")
-----8<-----

Reply via email to