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

Slow rule eval on WSL #1036

Closed
siennathesane opened this issue Jan 19, 2020 · 31 comments
Closed

Slow rule eval on WSL #1036

siennathesane opened this issue Jan 19, 2020 · 31 comments

Comments

@siennathesane
Copy link

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

% thefuck --version
The Fuck 3.29 using Python 3.8.1 and ZSH 5.4.2

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

% uname -r
4.19.84-microsoft-standard

image

How to reproduce the bug:

# linuxbrew using latest.
% brew install -v thefuck
% echo 'eval $(thefuck --alias fuck)' >> ~/.zshrc
% source ~/.zshrc

# some repo
% gitstatus
zsh: command not found: gitstatus

# this takes like 30 seconds.
% fuck

The output of The Fuck with THEFUCK_DEBUG=true exported (typically execute export THEFUCK_DEBUG=true in your shell before The Fuck):

 % fuck --debug
DEBUG: Run with settings: {'alter_history': True,
 'debug': True,
 'env': {'GIT_TRACE': '1', 'LANG': 'C', 'LC_ALL': 'C'},
 'exclude_rules': [],
 'history_limit': None,
 'instant_mode': True,
 'no_colors': False,
 'num_close_matches': 3,
 'priority': {},
 'repeat': False,
 'require_confirmation': True,
 'rules': [<const: All rules enabled>],
 'slow_commands': ['lein', 'react-native', 'gradle', './gradlew', 'vagrant'],
 'user_dir': PosixPath('/c/Users/MikeLloyd/.config/thefuck'),
 'wait_command': 3,
 'wait_slow_command': 15}
[WARN] PS1 doesn't contain user command mark, please ensure that PS1 is not changed after The Fuck alias initialization
DEBUG: Importing rule: adb_unknown_command; took: 0:00:00.000184
DEBUG: Importing rule: ag_literal; took: 0:00:00.000366
DEBUG: Importing rule: apt_get; took: 0:00:00.001400
DEBUG: Importing rule: apt_get_search; took: 0:00:00.000299
DEBUG: Importing rule: apt_invalid_operation; took: 0:00:00.000714
DEBUG: Importing rule: apt_list_upgradable; took: 0:00:00.000370
DEBUG: Importing rule: apt_upgrade; took: 0:00:00.000391
DEBUG: Importing rule: aws_cli; took: 0:00:00.000239
DEBUG: Importing rule: az_cli; took: 0:00:00.000561
DEBUG: Importing rule: brew_cask_dependency; took: 0:00:00.000493
DEBUG: Importing rule: brew_install; took: 0:00:00.000110
DEBUG: Importing rule: brew_link; took: 0:00:00.000261
DEBUG: Importing rule: brew_reinstall; took: 0:00:00.000484
DEBUG: Importing rule: brew_uninstall; took: 0:00:00.000239
DEBUG: Importing rule: brew_unknown_command; took: 0:00:00.000131
DEBUG: Importing rule: brew_update_formula; took: 0:00:00.000234
DEBUG: Importing rule: cargo; took: 0:00:00.000087
DEBUG: Importing rule: cargo_no_command; took: 0:00:00.000237
DEBUG: Importing rule: cat_dir; took: 0:00:00.000262
DEBUG: Importing rule: cd_correction; took: 0:00:00.001040
DEBUG: Importing rule: cd_mkdir; took: 0:00:00.000368
DEBUG: Importing rule: cd_parent; took: 0:00:00.000089
DEBUG: Importing rule: chmod_x; took: 0:00:00.000093
DEBUG: Importing rule: composer_not_command; took: 0:00:00.000252
DEBUG: Importing rule: cp_omitting_directory; took: 0:00:00.000365
DEBUG: Importing rule: cpp11; took: 0:00:00.000296
DEBUG: Importing rule: dirty_untar; took: 0:00:00.000876
DEBUG: Importing rule: dirty_unzip; took: 0:00:00.001614
DEBUG: Importing rule: django_south_ghost; took: 0:00:00.000222
DEBUG: Importing rule: django_south_merge; took: 0:00:00.000233
DEBUG: Importing rule: dnf_no_such_command; took: 0:00:00.085171
DEBUG: Importing rule: docker_login; took: 0:00:00.000305
DEBUG: Importing rule: docker_not_command; took: 0:00:00.083238
DEBUG: Importing rule: dry; took: 0:00:00.000133
DEBUG: Importing rule: fab_command_not_found; took: 0:00:00.000454
DEBUG: Importing rule: fix_alt_space; took: 0:00:00.000304
DEBUG: Importing rule: fix_file; took: 0:00:00.001708
DEBUG: Importing rule: gem_unknown_command; took: 0:00:00.013975
DEBUG: Importing rule: git_add; took: 0:00:00.000560
DEBUG: Importing rule: git_add_force; took: 0:00:00.000243
DEBUG: Importing rule: git_bisect_usage; took: 0:00:00.000315
DEBUG: Importing rule: git_branch_delete; took: 0:00:00.000273
DEBUG: Importing rule: git_branch_exists; took: 0:00:00.000307
DEBUG: Importing rule: git_branch_list; took: 0:00:00.000250
DEBUG: Importing rule: git_checkout; took: 0:00:00.000249
DEBUG: Importing rule: git_commit_amend; took: 0:00:00.000231
DEBUG: Importing rule: git_commit_reset; took: 0:00:00.000262
DEBUG: Importing rule: git_diff_no_index; took: 0:00:00.000296
DEBUG: Importing rule: git_diff_staged; took: 0:00:00.000367
DEBUG: Importing rule: git_fix_stash; took: 0:00:00.000320
DEBUG: Importing rule: git_flag_after_filename; took: 0:00:00.000329
DEBUG: Importing rule: git_help_aliased; took: 0:00:00.000309
DEBUG: Importing rule: git_merge; took: 0:00:00.000267
DEBUG: Importing rule: git_merge_unrelated; took: 0:00:00.000251
DEBUG: Importing rule: git_not_command; took: 0:00:00.000336
DEBUG: Importing rule: git_pull; took: 0:00:00.000260
DEBUG: Importing rule: git_pull_clone; took: 0:00:00.000250
DEBUG: Importing rule: git_pull_uncommitted_changes; took: 0:00:00.000264
DEBUG: Importing rule: git_push; took: 0:00:00.000240
DEBUG: Importing rule: git_push_different_branch_names; took: 0:00:00.000227
DEBUG: Importing rule: git_push_force; took: 0:00:00.000231
DEBUG: Importing rule: git_push_pull; took: 0:00:00.000270
DEBUG: Importing rule: git_push_without_commits; took: 0:00:00.000288
DEBUG: Importing rule: git_rebase_merge_dir; took: 0:00:00.000249
DEBUG: Importing rule: git_rebase_no_changes; took: 0:00:00.000221
DEBUG: Importing rule: git_remote_delete; took: 0:00:00.000247
DEBUG: Importing rule: git_remote_seturl_add; took: 0:00:00.000184
DEBUG: Importing rule: git_rm_local_modifications; took: 0:00:00.000264
DEBUG: Importing rule: git_rm_recursive; took: 0:00:00.000302
DEBUG: Importing rule: git_rm_staged; took: 0:00:00.000233
DEBUG: Importing rule: git_stash; took: 0:00:00.000233
DEBUG: Importing rule: git_stash_pop; took: 0:00:00.000260
DEBUG: Importing rule: git_tag_force; took: 0:00:00.000247
DEBUG: Importing rule: git_two_dashes; took: 0:00:00.000287
DEBUG: Importing rule: go_run; took: 0:00:00.000273
DEBUG: Importing rule: gradle_no_task; took: 0:00:00.001183
DEBUG: Importing rule: gradle_wrapper; took: 0:00:00.000379
DEBUG: Importing rule: grep_arguments_order; took: 0:00:00.000346
DEBUG: Importing rule: grep_recursive; took: 0:00:00.000372
DEBUG: Importing rule: grunt_task_not_found; took: 0:00:00.000639
DEBUG: Importing rule: gulp_not_task; took: 0:00:00.000453
DEBUG: Importing rule: has_exists_script; took: 0:00:00.000285
DEBUG: Importing rule: heroku_multiple_apps; took: 0:00:00.000331
DEBUG: Importing rule: heroku_not_command; took: 0:00:00.000280
DEBUG: Importing rule: history; took: 0:00:00.000137
DEBUG: Importing rule: hostscli; took: 0:00:00.000420
DEBUG: Importing rule: ifconfig_device_not_found; took: 0:00:00.000410
DEBUG: Importing rule: java; took: 0:00:00.000240
DEBUG: Importing rule: javac; took: 0:00:00.000303
DEBUG: Importing rule: lein_not_task; took: 0:00:00.000436
DEBUG: Importing rule: ln_no_hard_link; took: 0:00:00.000293
DEBUG: Importing rule: ln_s_order; took: 0:00:00.000463
DEBUG: Importing rule: long_form_help; took: 0:00:00.000143
DEBUG: Importing rule: ls_all; took: 0:00:00.000348
DEBUG: Importing rule: ls_lah; took: 0:00:00.000425
DEBUG: Importing rule: man; took: 0:00:00.000327
DEBUG: Importing rule: man_no_space; took: 0:00:00.000124
DEBUG: Importing rule: mercurial; took: 0:00:00.000345
DEBUG: Importing rule: missing_space_before_subcommand; took: 0:00:00.000105
DEBUG: Importing rule: mkdir_p; took: 0:00:00.000289
DEBUG: Importing rule: mvn_no_command; took: 0:00:00.000323
DEBUG: Importing rule: mvn_unknown_lifecycle_phase; took: 0:00:00.000367
DEBUG: Importing rule: no_command; took: 0:00:00.000398
DEBUG: Importing rule: no_such_file; took: 0:00:00.000180
DEBUG: Importing rule: npm_missing_script; took: 0:00:00.063259
DEBUG: Importing rule: npm_run_script; took: 0:00:00.000315
DEBUG: Importing rule: npm_wrong_command; took: 0:00:00.000378
DEBUG: Importing rule: open; took: 0:00:00.000335
DEBUG: Importing rule: pacman; took: 0:00:00.231445
DEBUG: Importing rule: pacman_not_found; took: 0:00:00.000160
DEBUG: Importing rule: path_from_history; took: 0:00:00.000129
DEBUG: Importing rule: php_s; took: 0:00:00.000312
DEBUG: Importing rule: pip_install; took: 0:00:00.000308
DEBUG: Importing rule: pip_unknown_command; took: 0:00:00.000300
DEBUG: Importing rule: port_already_in_use; took: 0:00:00.000678
DEBUG: Importing rule: prove_recursively; took: 0:00:00.000411
DEBUG: Importing rule: pyenv_no_such_command; took: 0:00:00.080183
DEBUG: Importing rule: python_command; took: 0:00:00.000285
DEBUG: Importing rule: python_execute; took: 0:00:00.000244
DEBUG: Importing rule: quotation_marks; took: 0:00:00.000087
DEBUG: Importing rule: react_native_command_unrecognized; took: 0:00:00.000309
DEBUG: Importing rule: remove_trailing_cedilla; took: 0:00:00.000127
DEBUG: Importing rule: rm_dir; took: 0:00:00.000255
DEBUG: Importing rule: rm_root; took: 0:00:00.000272
DEBUG: Importing rule: scm_correction; took: 0:00:00.000289
DEBUG: Importing rule: sed_unterminated_s; took: 0:00:00.000260
DEBUG: Importing rule: sl_ls; took: 0:00:00.000130
DEBUG: Importing rule: ssh_known_hosts; took: 0:00:00.000262
DEBUG: Importing rule: sudo; took: 0:00:00.000120
DEBUG: Importing rule: sudo_command_from_user_path; took: 0:00:00.000261
DEBUG: Importing rule: switch_lang; took: 0:00:00.000167
DEBUG: Importing rule: systemctl; took: 0:00:00.000388
DEBUG: Importing rule: test.py; took: 0:00:00.000100
DEBUG: Importing rule: tmux; took: 0:00:00.000286
DEBUG: Importing rule: touch; took: 0:00:00.000509
DEBUG: Importing rule: tsuru_login; took: 0:00:00.000273
DEBUG: Importing rule: tsuru_not_command; took: 0:00:00.000245
DEBUG: Importing rule: unknown_command; took: 0:00:00.000114
DEBUG: Importing rule: unsudo; took: 0:00:00.000108
DEBUG: Importing rule: vagrant_up; took: 0:00:00.000251
DEBUG: Importing rule: whois; took: 0:00:00.000368
DEBUG: Importing rule: workon_doesnt_exists; took: 0:00:00.000312
DEBUG: Importing rule: yarn_alias; took: 0:00:00.000248
DEBUG: Importing rule: yarn_command_not_found; took: 0:00:00.086066
DEBUG: Importing rule: yarn_command_replaced; took: 0:00:00.000458
DEBUG: Importing rule: yarn_help; took: 0:00:00.000263
DEBUG: Trying rule: dirty_unzip; took: 0:00:00.000111
No fucks given
DEBUG: Total took: 0:00:27.193200

If the bug only appears with a specific application, the output of that application and its version:

It seems to be slow regardless.

Anything else you think is relevant:

I'm not really sure what would cause it to evaluate slowly, each rule import and eval only takes a couple milliseconds, so it's not the eval it feels like there's a 20 second wait for it to spin up before it starts evaluating.

@siennathesane
Copy link
Author

I also tried this with instance mode disabled and had the same results.

@B3Kay
Copy link

B3Kay commented Feb 24, 2020

I have the same issue, Just installed TheFuck on my wsl 2 ubuntu, on windows 10 and it's pritty slow. Takes a few seconds beofore something happens.

@dopdahl16
Copy link

I also have the same issue with WSL on Windows 10 and The Fuck 3.29 using Python 3.6.9 and Bash 4.4.20(1)-release
From purely anecdotal experience, it seems like git commands take the longest for fuck to return options.

@siennathesane
Copy link
Author

So I've noticed overall that WSL2 is just slower when it's running on a spindle, so I'm chalking my performance up to that. I'm going to move it from my spindle to a solid state this week and see if that resolves my problem.

@PePoDev
Copy link

PePoDev commented Jul 2, 2020

Same problem on WSL 2 ubuntu 18.04
Install with pip3

$ thefuck --version
The Fuck 3.30 using Python 3.8.2 and ZSH 5.8

@flawiddsouza
Copy link

I'm on a SSD and it's still pretty slow. Takes like 10-20 seconds to return anything.

@nasht
Copy link

nasht commented Jul 6, 2020

Same issue as the folks above. Ubuntu 18 and 20 on WSL, and thefuck is thefucking slow :)

@miking-the-viking
Copy link

miking-the-viking commented Jul 7, 2020

  • WSL2
  • The Fuck 3.30
  • Python 3.8.2
  • ZSH 5.8
  • Windows 10 19041.329
  • i9-9900K
  • 32 GB DDR4 4000
  • Samsung 970 EVO Plus 2TB internal NVMe SSD

.... It's not a machine performance issue as far as I can deduce.

thefuck test 0.44s user 0.49s system 22% cpu 4.217 total -

I've just reformatted my pc from the Insiders to Stable (as WSL2 is on the stable release) and have noticed a marked improvement to thefuck response time. However it is still nothing like when on OS X or native Linux.

@kimlym
Copy link

kimlym commented Aug 3, 2020

Hey guys, I figured this out. it's irrelevant to thefuck but your wsl machine.

Try echo $PATH and you probably gonna see a long list there, and that's the reason the fuck is so slow. You can do what's suggested here, microsoft/WSL#1640 (comment), and restart your linux distro.

After that thefuck runs smooth as fuck for me

Beware your vscode would be gone after that, so probably do which code first

@dopdahl16
Copy link

Testing @kimlym 's solution:
$ echo $PATH
I'm going to refrain from displaying my entire PATH for privacy reasons, but mine had 34 entries.
I ran 10 tests of thefuck using the following sequence:

my_user@my_machine:/some/non-git/directory$ git staus
git: 'staus' is not a git command. See 'git --help'.
The most similar command is
status
my_user@my_machine:/some/non-git/directory$ time fuck
git status [enter/↑/↓/ctrl+c]
fatal: not a git repository
real XmX.XXs
user XmX.XXs
sys XmX.XXs

The average of the user times was: 0.336
The average of the sys times was: 1.7954
We don't care about the real time since that includes I/O. To better understand the output of time, see here

After removing the appended Windows path as @kimlym suggested here , running $ echo $PATH now only returns 11 entries.
Repeating the same sequence of tests:
The average of the user times was: 0.2032
The average of the sys times was: 0.2157

This represents a 40% reduction in user time, and a 88% reduction in sys time.
So it does seem like shortening the PATH does help thefuck run faster.

However, it would be desirable for thefuck to run quickly with a longer PATH... Maybe investigating into why there is such a large increase in sys time for a longer PATH would lead to something promising?

@PePoDev
Copy link

PePoDev commented Aug 5, 2020

Problem when remove path env on Windows side is VSCode can't open in command.

$ which code
/c/Program Files/Microsoft VS Code/bin/code

@kimlym
Copy link

kimlym commented Aug 5, 2020

@PePoDev you can add that to your path in your bashrc or w/e shell file, something like this

PATH=$PATH:/c/Program Files/Microsoft VS Code/bin/code

Might need an export on that. And for my case it's /mnt/c

@PePoDev
Copy link

PePoDev commented Aug 5, 2020

I not sure in the future something will broke again or not about Windows path.

@Electronics
Copy link

Electronics commented Aug 24, 2020

Whilst removing the windows entries in $PATH, specifically the windows/system32 directory, does drastically improve times, this means that running windows applications from within the WSL environment is relatively limited without having to utilise full paths for everything.

@DoNotResuscitate
Copy link

So there is no found explanation for why having Windows entries in path makes thefuck take such a long time?

@cforce
Copy link

cforce commented Sep 19, 2020

image

@Schwaitz
Copy link

I created a new Wiki page called Troubleshooting and added this fix to it. I'm not familiar with any style guidelines for Github Wiki pages (if there even is such a thing), so feel free to edit it if something doesn't look right!

@cforce
Copy link

cforce commented Jan 15, 2021

fuck yeah :) So this can be closed, don't it?

@PePoDev
Copy link

PePoDev commented Jan 15, 2021

@cforce I think set appendWindowsPath to false is not a good solution. Just for now or some one.

If remove env path from Windows side it will make VSCode can't open in command on WSL. Maybe in another program will cause the same issue.

My opinion is thefuck should detect WSL and exclude Windows path by default or make some ENV variable to add prefix path to exclude from thefuck ?

@stuartleeks
Copy link
Contributor

I've created PR (#1165) which adds a setting to allow filtering paths - this could be used to prevent searching in /mnt paths under WSL which improves performance without needing to disable adding Windows paths to WSL (which has other negative side effects as noted in this thread)

@swirle13
Copy link

@stuartleeks How would one go about implementing your PR?

@stuartleeks
Copy link
Contributor

You mean how to run the PR version? If so, the way I'm using it is cloning the repo and checking out the PR branch. From there you can follow the CONTRIBUTING.md steps to install.

This will allow you to configure the excluded_search_path_prefixes to filter out the Windows mounts. E.g. in settings.py you can add:

excluded_search_path_prefixes = ['/mnt/']

@swirle13
Copy link

swirle13 commented Apr 16, 2021

@stuartleeks ahh, I had done everything to take your updates and import them into the current v3.30 but I wasn't seeing any improvement. Totally forgot to add that to settings. Thanks!

The performance change is insanely drastic.

Without your PR:

$ cs

Command 'cs' not found, but can be installed with:

sudo apt install csound

$ time fuck
cd [enter/↑/↓/ctrl+c]
Aborted

real    0m21.477s
user    0m1.659s
sys     0m2.910s

With your PR:

$ cs

Command 'cs' not found, but can be installed with:

sudo apt install csound

$ time fuck
cd [enter/↑/↓/ctrl+c]
Aborted

real    0m1.382s
user    0m0.348s
sys     0m0.030s

And this is on a 256gb ssd on my work laptop. So even though real time includes IO, that's a very real time impact for my day to day use. I'm honestly contemplating forking and uploading this fixed version to my page.

@pdavies
Copy link

pdavies commented Jun 2, 2021

Hi, I found this issue after hitting the same thing. Is it right that #1165 closed this issue? Users (like myself) who install the next thefuck release on WSL will still hit a borderline-unusable delay with no indication of why. To fix it, the user has to care enough to start googling instead of just abandoning the tool, track down this github issue (surprisingly nontrivial unless you have prior knowledge that the issue is WSL-specific), find the comment or the MR with the exclusion setting, and apply it. It's a huge improvement to have a setting available to resolve the issue on my box, and that's fantastic, but it's workaround, not a fix.

As a crude starting point, what about defaulting excluded_search_path_prefixes to ["/mnt/c/WINDOWS"]?

  • In my profiling, system32 accounted for a large majority of the time penalty, and the rest of C:\Windows accounted for a large majority of the remainder
  • Most people have Windows mounted on C:
  • Yes this "stops" people from using thefuck for C:\Windows executables while on WSL. But they already couldn't do that - the perf was basically unusable

I'm not saying that's an excellent solution by any stretch, and hope it provokes better alternatives, but isn't it better than the current state?

@scorphus
Copy link
Collaborator

It would be a nice addition to Troubleshooting and useful to those that prefer not having appendWindowsPath = false in their WSL config.

@Temez1
Copy link

Temez1 commented Sep 16, 2021

I think in installation there should be a section for WSL.

And under that section it should mention about that excluded_search_path_prefixes = ['/mnt/'] setting explicitly.

It's not the best DX to start fixing a program after installing it and this would be an easy way to improve the DX.

@scorphus
Copy link
Collaborator

That would be a nice thing to have. Any ideas how that can be done? PR's are more than welcome.

@Temez1
Copy link

Temez1 commented Sep 16, 2021

That would be a nice thing to have. Any ideas how that can be done? PR's are more than welcome.

Did that, see #1236. Also, I couldn't help with the more examples.. #1235

@scorphus
Copy link
Collaborator

Oh, I thought you meant the installation process.

@just-Bri
Copy link

just-Bri commented Oct 13, 2021

As a crude starting point, what about defaulting excluded_search_path_prefixes to ["/mnt/c/WINDOWS"]?

I'm not saying that's an excellent solution by any stretch, and hope it provokes better alternatives, but isn't it better than the current state?

I tried this, as well as just using /mnt, but I'm still experiencing extremely slow performance.

image

Has anyone come up with any other solutions/workarounds/hacks?

EDIT: Almost immediately after posting this comment I noticed my path has a lot of references to /c rather than /mnt/c, changing the excluse to include '/c' improved performance to what I am used to on native Mac/Linux.
I'm expecting this has something to do with our setup at my job, but wanted to leave a note of this here.

@glaucusec
Copy link

Hey guys, I figured this out. it's irrelevant to thefuck but your wsl machine.

Try echo $PATH and you probably gonna see a long list there, and that's the reason the fuck is so slow. You can do what's suggested here, microsoft/WSL#1640 (comment), and restart your linux distro.

After that thefuck runs smooth as fuck for me

Beware your vscode would be gone after that, so probably do which code first

Thanks this worked fine for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests