nvbn / thefuck

Magnificent app which corrects your previous console command.
MIT License
83.62k stars 3.41k forks source link

Shell slow to start with `eval "$(thefuck --alias)"`, workaround is a lazy loading trick #1428

Open mooreye opened 5 months ago

mooreye commented 5 months ago

The output of thefuck --version (something like The Fuck 3.1 using Python 3.5.0 and Bash 4.4.12(1)-release):

The Fuck 3.32 using Python 3.12.1 and Bash 5.2.21(1)-release

Your system (Debian 7, ArchLinux, Windows, etc.):

Fedora 39

How to reproduce the bug:

Put eval $(thefuck --alias) in ~/.bashrc and observe that the shell is noticeably slower to start than without it.

Time without:

$ time bash -ic ''

real    0m0.055s
user    0m0.037s
sys 0m0.019s

Time with:

$ time bash -ic ''

real    0m0.263s
user    0m0.219s
sys 0m0.043s

Anything else you think is relevant:

If there is nothing that can be done to fix this, the following lazy loading trick works for me:

alias fuck='if ! declare -f fuck &>/dev/null; then eval -- "$(thefuck -a)"; fi && fuck'

Maybe this should be added to the docs somehow?

pallaswept commented 2 months ago

Came to report this same issue. For some reason, thefuck --alias takes ~100ms to return, on a 5900X... Similar functions (zoxide init, starship init, etc) take ~2ms here.

time thefuck --alias

            function fuck () {
                TF_PYTHONIOENCODING=$PYTHONIOENCODING;
                export TF_SHELL=bash;
                export TF_ALIAS=fuck;
                export TF_SHELL_ALIASES=$(alias);
                export TF_HISTORY=$(fc -ln -10);
                export PYTHONIOENCODING=utf-8;
                TF_CMD=$(
                    thefuck THEFUCK_ARGUMENT_PLACEHOLDER "$@"
                ) && eval "$TF_CMD";
                unset TF_HISTORY;
                export PYTHONIOENCODING=$TF_PYTHONIOENCODING;
                history -s $TF_CMD;
            }

real    0m0.097s
user    0m0.085s
sys     0m0.012s
[elapsed: 97ms (CPU 99.0%)] time thefuck --alias

My workaround rather than lazy loading was simply to use the output of the command directly in my bashrc. I'll need to re-do that if the output changes and thefuck breaks in future, but the performance is better.