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

windows git bash: Listing aliases is very slow #3054

Closed
bbrk24 opened this issue Mar 9, 2023 · 6 comments · Fixed by #3060
Closed

windows git bash: Listing aliases is very slow #3054

bbrk24 opened this issue Mar 9, 2023 · 6 comments · Fixed by #3060
Labels
OS: windows performance This relates to anything regarding the speed of using nvm. pull request wanted This is a great way to contribute! Help us out :-D shell: git bash/cygwin

Comments

@bbrk24
Copy link
Contributor

bbrk24 commented Mar 9, 2023

Operating system and version:

Windows 10

nvm debug output:

nvm --version: v0.39.3
$TERM_PROGRAM: mintty
$SHELL: /usr/bin/bash
$SHLVL: 1
whoami: 'bbrk2'
${HOME}: /c/Users/bbrk2
${NVM_DIR}: '${HOME}/.nvm'
${PATH}: ${NVM_DIR}/versions/node/v18.14.1/bin:/bin:/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/c/Program Files (x86)/nodejs:/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/c/Program Files/Common Files/Oracle/Java/javapath:/c/Program Files/dotnet:/c/Program Files/MATLAB/R2020b/bin:/c/Program Files/Microsoft SQL Server/130/Tools/Binn:/c/Program Files/NVIDIA Corporation/NVIDIA NvDLISR:${HOME}/.cargo/bin:${HOME}/.dotnet/tools:${HOME}/AppData/Local/Microsoft/WindowsApps:${HOME}/AppData/Local/Programs/Microsoft VS Code/bin:${HOME}/AppData/Local/Programs/Python/Python39:${HOME}/AppData/Local/Programs/Python/Python39/Scripts:${HOME}/AppData/Roaming/npm:${HOME}/AppData/Roaming/Python/Python37/Scripts:${HOME}/source/repos/emsdk/upstream/bin:${HOME}/source/repos/emsdk/upstream/emscripten:/c/WINDOWS:/c/WINDOWS/system32:/c/Windows/System32/downlevel:/c/WINDOWS/System32/OpenSSH:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/cmd:/mingw64/bin:/usr/bin:/usr/bin/core_perl:/usr/bin/vendor_perl
$PREFIX: ''
${NPM_CONFIG_PREFIX}: ''
$NVM_NODEJS_ORG_MIRROR: ''
$NVM_IOJS_ORG_MIRROR: ''
shell version: 'GNU bash, version 4.4.23(1)-release (x86_64-pc-msys)'
uname -a: 'MINGW64_NT-10.0-19045 3.3.5-341.x86_64 2022-07-08 09:41 UTC x86_64 Msys'
checksum binary: 'sha256sum'
awk: /bin/awk, GNU Awk 5.0.0, API: 2.0 (GNU MPFR 4.1.0-p13, GNU MP 6.2.1)
curl: /c/WINDOWS/system32/curl, curl 7.83.1 (Windows) libcurl/7.83.1 Schannel
wget: not found
git: /cmd/git, git version 2.37.1.windows.1
grep: /bin/grep, grep (GNU grep) 3.0
sed: /bin/sed, sed (GNU sed) 4.8
cut: /bin/cut, cut (GNU coreutils) 8.32
basename: /bin/basename, basename (GNU coreutils) 8.32
rm: /bin/rm, rm (GNU coreutils) 8.32
mkdir: /bin/mkdir, mkdir (GNU coreutils) 8.32
xargs: /bin/xargs, xargs (GNU findutils) 4.9.0
nvm current: 
which node: ${NVM_DIR}/versions/node/v18.14.1/bin/node
which iojs: which: no iojs in (${NVM_DIR}/versions/node/v18.14.1/bin:/bin:/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/c/Program Files (x86)/nodejs:/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/c/Program Files/Common Files/Oracle/Java/javapath:/c/Program Files/dotnet:/c/Program Files/MATLAB/R2020b/bin:/c/Program Files/Microsoft SQL Server/130/Tools/Binn:/c/Program Files/NVIDIA Corporation/NVIDIA NvDLISR:${HOME}/.cargo/bin:${HOME}/.dotnet/tools:${HOME}/AppData/Local/Microsoft/WindowsApps:${HOME}/AppData/Local/Programs/Microsoft VS Code/bin:${HOME}/AppData/Local/Programs/Python/Python39:${HOME}/AppData/Local/Programs/Python/Python39/Scripts:${HOME}/AppData/Roaming/npm:${HOME}/AppData/Roaming/Python/Python37/Scripts:${HOME}/source/repos/emsdk/upstream/bin:${HOME}/source/repos/emsdk/upstream/emscripten:/c/WINDOWS:/c/WINDOWS/system32:/c/Windows/System32/downlevel:/c/WINDOWS/System32/OpenSSH:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/cmd:/mingw64/bin:/usr/bin:/usr/bin/core_perl:/usr/bin/vendor_perl)
which npm: ${NVM_DIR}/versions/node/v18.14.1/bin/npm
npm config get prefix: C:\Users\bbrk2\.nvm\versions\node\v18.14.1\bin
npm root -g: C:\Users\bbrk2\.nvm\versions\node\v18.14.1\bin\node_modules

nvm ls output:

      v12.22.12
       v14.21.3
       v16.19.1
       v18.14.1
         system
default -> lts/* (-> v18.14.1)
v14.17 -> v14.17.0 (-> system)
v14.17.0 -> system
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v18.14.1) (default)
stable -> 18.14 (-> v18.14.1) (default)
lts/* -> lts/hydrogen (-> v18.14.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12
lts/fermium -> v14.21.3
lts/gallium -> v16.19.1
lts/hydrogen -> v18.14.1

How did you install nvm?

I don't remember for certain. I either used the curl script in the README, or cloned the git repo directly.

What steps did you perform?

Simply run nvm ls or nvm alias with no arguments.

What happened?

It takes 20-30 seconds to complete (though of course nvm alias is faster than nvm ls):

$ time ( nvm ls >/dev/null )

real    0m22.039s
user    0m9.907s
sys     0m28.437s

$ time ( nvm alias >/dev/null )

real    0m17.515s
user    0m8.056s
sys     0m27.040s

Most of this time is spent in nvm_list_aliases:

$ time ( nvm_list_aliases >/dev/null )

real    0m16.067s
user    0m8.567s
sys     0m25.223s

What did you expect to happen?

The output should display in a reasonable amount of time; cf. nvm ls --no-alias:

$ time ( nvm ls --no-alias >/dev/null )

real    0m4.600s
user    0m0.941s
sys     0m2.141s

I noticed that a slight modification to nvm_list_aliases (only calling wait and sort once each) sped it up significantly:

$ time ( nvm_list_aliases_onesort_onewait >/dev/null )

real    0m9.780s
user    0m8.548s
sys     0m29.593s

Of course, the order of the output is slightly different, but I don't mind that.

The code for nvm_list_aliases_onesort_onewait
nvm_list_aliases_onesort_onewait ()
{ 
    local ALIAS;
    ALIAS="${1-}";
    local NVM_CURRENT;
    NVM_CURRENT="$(nvm_ls_current)";
    local NVM_ALIAS_DIR;
    NVM_ALIAS_DIR="$(nvm_alias_path)";
    command mkdir -p "${NVM_ALIAS_DIR}/lts";
    if [ "${ALIAS}" != "${ALIAS#lts/}" ]; then
        nvm_alias "${ALIAS}";
        return $?;
    fi;
    nvm_is_zsh && unsetopt local_options nomatch;
    (
    local ALIAS_PATH;
    for ALIAS_PATH in "${NVM_ALIAS_DIR}/${ALIAS}"*;
    do
        NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_CURRENT="${NVM_CURRENT}" nvm_print_alias_path "${NVM_ALIAS_DIR}" "${ALIAS_PATH}" &
    done;
    local ALIAS_NAME;
    for ALIAS_NAME in "$(nvm_node_prefix)" "stable" "unstable";
    do
        { 
            if [ ! -f "${NVM_ALIAS_DIR}/${ALIAS_NAME}" ] && { 
                [ -z "${ALIAS}" ] || [ "${ALIAS_NAME}" = "${ALIAS}" ]
            }; then
                NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_CURRENT="${NVM_CURRENT}" nvm_print_default_alias "${ALIAS_NAME}";
            fi
        } &
    done;
    ALIAS_NAME="$(nvm_iojs_prefix)";
    if [ ! -f "${NVM_ALIAS_DIR}/${ALIAS_NAME}" ] && { 
        [ -z "${ALIAS}" ] || [ "${ALIAS_NAME}" = "${ALIAS}" ]
    }; then
        NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_CURRENT="${NVM_CURRENT}" nvm_print_default_alias "${ALIAS_NAME}";
    fi
    local LTS_ALIAS;
    for ALIAS_PATH in "${NVM_ALIAS_DIR}/lts/${ALIAS}"*;
    do
        { 
            LTS_ALIAS="$(NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_LTS=true nvm_print_alias_path "${NVM_ALIAS_DIR}" "${ALIAS_PATH}")";
            if [ -n "${LTS_ALIAS}" ]; then
                nvm_echo "${LTS_ALIAS}";
            fi
        } &
    done;
    wait ) | sort
    return
}

Is there anything in any of your profile files that modifies the PATH?

Yes. I have the following excerpt in my .bash_profile:

# $PATH contains duplicates and nonexistent directories. Fix that.
PATH=$(echo "${PATH//:/
}" | sort -f | uniq -i | while IFS= read -r dir
do
    test -d "$dir" && echo "$dir"
done | paste -sd:)
export PATH

While the times given above are with this excerpt, nvm ls was slow before I added it.

@ljharb
Copy link
Member

ljharb commented Mar 9, 2023

What version of WSL are you using?

@bbrk24
Copy link
Contributor Author

bbrk24 commented Mar 9, 2023

I don't use WSL, actually, I'm using Git Bash for Windows. According to their --version flags, I have git 2.37.1.windows.1 and bash 4.4.23(1)-release (x86_64-pc-msys).

@ljharb ljharb added OS: windows performance This relates to anything regarding the speed of using nvm. shell: git bash/cygwin labels Mar 10, 2023
@ljharb ljharb changed the title Listing aliases is very slow windows git bash: Listing aliases is very slow Mar 10, 2023
@ljharb
Copy link
Member

ljharb commented Mar 10, 2023

ah, gotcha. There's not been extensive usage in git bash, so performance issues aren't surprising.

If there's changes that we can make that maintain correctness while improving performance, I'm always happy to review a PR :-)

@ljharb ljharb added the pull request wanted This is a great way to contribute! Help us out :-D label Mar 10, 2023
@bbrk24
Copy link
Contributor Author

bbrk24 commented Mar 10, 2023

I'm investigating this a bit more to see if performance can be improved without changing output order. Even a single invocation of nvm_print_alias_path takes about three seconds:

$ time ( nvm_print_alias_path $NVM_DIR/alias default >/dev/null )

real    0m2.966s
user    0m0.439s
sys     0m1.281s

and I have 12 aliases set up, so this function could account for the vast majority of the sys time.

Edit: the majority of that is a single nvm_print_formatted_alias, and I'm not yet sure why.

Edit 2: continuing down the chain, nvm_version is surprisingly slow:

$ time nvm_version default
v18.14.1

real    0m2.115s
user    0m0.196s
sys     0m0.814s

@bbrk24
Copy link
Contributor Author

bbrk24 commented Mar 10, 2023

I have a potential improvement: it speeds up nvm ls by anywhere from 5% to 30% depending on the run. However, I can't test it. npm test tells me (even if invoked from bash and not cmd):


> nvm@0.39.3 test
> shell=$(basename -- $(ps -o comm= $(ps -o ppid= -p $PPID)) | sed 's/^-//'); make test-$shell

'shell' is not recognized as an internal or external command,
operable program or batch file.

I know that cross-env was designed to prevent this, but I don't want to add a new dependency. Regardless, my ps doesn't recognize the -o flag, so even if I paste this directly in bash it doesn't run.

bbrk24 added a commit to bbrk24/nvm that referenced this issue Mar 10, 2023
@ljharb
Copy link
Member

ljharb commented Mar 10, 2023

If you push up a branch to your fork, github actions should run the tests for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OS: windows performance This relates to anything regarding the speed of using nvm. pull request wanted This is a great way to contribute! Help us out :-D shell: git bash/cygwin
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants