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

syntax highlighting is super slow in WSL2 #790

Open
A1ex-N opened this issue Dec 29, 2020 · 24 comments
Open

syntax highlighting is super slow in WSL2 #790

A1ex-N opened this issue Dec 29, 2020 · 24 comments

Comments

@A1ex-N
Copy link

A1ex-N commented Dec 29, 2020

On WSL the zsh syntax highlighting worked perfectly, but in WSL2 it's extremely slow. When you type there's about a 1 second delay before your input is actually shown. Not sure if it's a problem with WSL2 or the highlighting itself.

@danielshahaf
Copy link
Member

What are the version numbers of zsh and zsh-syntax-highlighting in each environment?

@A1ex-N
Copy link
Author

A1ex-N commented Dec 29, 2020

@danielshahaf I'm on zsh 5.8 and the latest version of zsh syntax highlighting installed via git clone. I'm using Ubuntu-20,04 via WSL2

@danielshahaf
Copy link
Member

danielshahaf commented Dec 30, 2020 via email

@Purewhiter
Copy link

encounter the same issue

@danielshahaf
Copy link
Member

To answer the deleted comment: z-sy-h uses $PATH via the type builtin to determine whether a command word should be highlighted in green or red. However, an expensive-to-access $PATH wouldn't by itself explain slowness after the command word has finished being inputted, since both z-sy-h and zsh memoize the results of filesystem queries. Related knobs include zsh's PATH_DIRS and HASH_CMDS options and related options in that section, and the rehash builtin and style. z-sy-h's memoization takes place in _zsh_highlight_main__type.

That can be ruled out simply by trying to reproduce the issue under zsh -f (and then sourcing zsh-syntax-highlighting.zsh manually).

@twobiers
Copy link

twobiers commented Aug 21, 2022

I noticed some sluggish behaviour while on WSL2 but nothing like a 1 second delay (if I had to guess about ~200ms).
The only thing that should be slow on WSL2 would be the NTFS mounts from the windows file system as they are mounted by using 9P.
I have added the windows mount in the directory blacklist as mentioned here: https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/main.md#parameters

ZSH_HIGHLIGHT_DIRS_BLACKLIST+=(/mnt/c)

This makes the "cold" highlighting after a fresh start a bit faster. Surprisingly enough it still recognizes commands like code as valid commands and highlights them green/red accordingly although being located in /mnt/c/. However, as mentioned by @danielshahaf the Path lookups are memorized and it shouldn't make that big difference.

@wywywywy
Copy link

wywywywy commented Nov 7, 2022

Adding ZSH_HIGHLIGHT_DIRS_BLACKLIST doesn't seem to change anything.

Is there anything else to try?

@danielshahaf
Copy link
Member

Try zsh 5.9.
I don't know that any maintainer has WSL, so, y'all may need to help investigate. Does it reproduce in zsh -f? Do make check and make perf work? Does zsh/zprof show anything (don't forget to zprof -c before starting the timed section)? Can you try a different terminal?

(I just posted that on #899, but it works equally well as an answer to @wywywywy.)

@amimof
Copy link

amimof commented Jan 17, 2023

I solved this by excluding windows directories from $PATH by adding following in /etc/wsl.conf. Create the file if it doesn't exist

[interop]
appendWindowsPath = false

Then restart wsl with

wsl --shutdown

It's also possible to disable the possibility to run windows binaries inside WSL instances with the following in /etc/wsl.conf. I didn't do this myself since the above solved my performance problems I had

enabled = false

@patrick-5546
Copy link

patrick-5546 commented Jan 17, 2023

I solved this by excluding windows directories from $PATH by adding following in /etc/wsl.conf. Create the file if it doesn't exist

[interop]
appendWindowsPath = false

For my use case I still want some Windows paths. For example the code command is found in /mnt/c/Users/<user>/AppData/Local/Programs/Microsoft VS Code/bin

@A1ex-N
Copy link
Author

A1ex-N commented Jan 17, 2023

I solved this by excluding windows directories from $PATH by adding following in /etc/wsl.conf. Create the file if it doesn't exist

[interop]
appendWindowsPath = false

For my use case I still want some Windows paths. For example the code command is found in /mnt/c/Users/pcrei/AppData/Local/Programs/Microsoft VS Code/bin

You could make some aliases for your common windows commands if you still wanted to exclude the windows directories from the $PATH. For example alias code=/mnt/c/vscode.exe

@patrick-5546
Copy link

patrick-5546 commented Jan 18, 2023

I ended up manually adding that bin to PATH, which didn't noticeably slow down performance:

export PATH="/mnt/c/Users/<user>/AppData/Local/Programs/Microsoft VS Code/bin:$PATH"

I wonder which windows paths causes the poor performance of syntax highlighting.

@A1ex-N
Copy link
Author

A1ex-N commented Jan 18, 2023

I ended up manually adding that bin to PATH, which didn't noticeably slow down performance:

export PATH="/mnt/c/Users/<user>/AppData/Local/Programs/Microsoft VS Code/bin:$PATH"

I wonder which windows paths causes the poor performance of syntax highlighting.

I imagine it's not any specific paths that causes the slowdown, it's probably just the number of paths.

@danielshahaf
Copy link
Member

@amimof Thanks for the info that removing some entries from $path resolves the slowness.

First, I'd like to check whether there are any other causes of slowness at play here. So:

  1. After applying the workaround proposed in syntax highlighting is super slow in WSL2 #790 (comment) by @amimof, does anyone observe slowness that isn't covered by some other open issue? [Note I haven't reviewed the workaround.]

  2. Does slowness happen at words other than command words? For instance, when completing --options, arguments to them, or positional arguments (filenames to ls(1), hostname to ping(1), etc.).

  3. There's caching going on, both at the zsh level (see the rehash builtin) and at the z-sy-h level (in _zsh_highlight_main__type()). Negative matches are cached at the z-sy-h level — to see that, run print -raC2 - "${(@kv)_zsh_highlight_main__command_type_cache}" and observe the none entries — so, in theory, once you've typed foobar in command position once, the next time you type foobar in command position will be highlighted quickly. Is that what happens?

@lesmo
Copy link

lesmo commented Jan 23, 2023

I wonder which windows paths causes the poor performance of syntax highlighting.

I imagine it's not any specific paths that causes the slowdown, it's probably just the number of paths.

WSL2 is well known to have poor performance interacting with Windows' filesystem. There's an open issue dating back to 2019: microsoft/WSL#4197

Workarounds include working inside WSL2's filesystem or creating an NFS server and use that instead (which funnily enough, seems to work faster than the native WSL2's way of doing it).

This performance issue directly affects anything that has to do with Windows' path, to list a couple:

I solved this by excluding windows directories from $PATH by adding following in /etc/wsl.conf. Create the file if it doesn't exist

[interop]
appendWindowsPath = false

This workaround "solves" the problem. By removing Window's paths from WSL2 we won't take the performance hit of doing lookups outside Linux... but we lose a bit of the cool integration with Windows.

Using ZSH_HIGHLIGHT_DIRS_BLACKLIST should help, but I'm not sure why it still feels slow... it's as if there were still some lookups happening on Windows's filesystem. Maybe there's some other paths that are symlinks to Windows? I'm not sure how to go about trying to figure that one out.

From what I can gather, the /mnt/c/WINDOWS/System32 path has a lot of files and is most likely the culprit here: it has over 5k items!

So added this appendWindowsPath flag and re-added some of my Windows' paths to my .zshrc (including the Windows folder itself), and the slowness is gone for me (these are most likely what the average coder using WSL2 will need anyway):

# .zshrc
### Windows ###
export PATH="$PATH:/mnt/c/Users/lesmo/AppData/Local/Microsoft/WindowsApps"
export PATH="$PATH:/mnt/c/Users/lesmo/AppData/Local/Programs/Microsoft VS Code/bin"
export PATH="$PATH:/mnt/c/Program Files/Docker/Docker/resources/bin"
export PATH="$PATH:/mnt/c/ProgramData/DockerDesktop/version-bin"
export PATH="$PATH:/mnt/c/WINDOWS"

Maybe we just need to figure out why ZSH_HIGHLIGHT_DIRS_BLACKLIST doesn't seem to work?

@danielshahaf
Copy link
Member

danielshahaf commented Jan 24, 2023 via email

@Mukiik
Copy link

Mukiik commented Feb 22, 2023

I solved this by excluding windows directories from $PATH by adding following in /etc/wsl.conf. Create the file if it doesn't exist

[interop]
appendWindowsPath = false

Then restart wsl with

wsl --shutdown

It's also possible to disable the possibility to run windows binaries inside WSL instances with the following in /etc/wsl.conf. I didn't do this myself since the above solved my performance problems I had

enabled = false

@amimof Thanks, that's useful for me.

@Mark4551124015
Copy link

marked, helped me as well

@jteng2127
Copy link

same problem here, but I still want to keep windows path in WSL2, because I often use windows commands like clip.exe, cmd.exe, etc. and I don't want to alias all command one by one, that will be annoying.

maybe there's a bug of ZSH_HIGHLIGHT_DIRS_BLACKLIST?

@khaitranhq
Copy link

Thank you @amimof, it worked for me.

@ShelpAm
Copy link

ShelpAm commented Jul 19, 2023

Thank you! That helps a lot!

@BearyDevs
Copy link

Thank you @amimof, It's propery worked fine

@kamalciirs
Copy link

Thank you @amimof, It's worked perfectly.

@ylu3
Copy link

ylu3 commented Dec 11, 2024

Thank you @amimof!

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

No branches or pull requests