-
Notifications
You must be signed in to change notification settings - Fork 196
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
Apparent formatter speed regression #381
Comments
Same here :( |
Do you have a sample project that exhibits this issue? And what is in your |
Unfortunately I don't have a sample repro :/ We're in an umbrella project, so here's the contents of our various formatter configs:
|
I'm getting this in the output:
Maybe it helps. |
@BlueHotDog do you have any file open from |
this is my .formatter:
I do not have any file from deps/delemetry.. open :( |
Hmm the code in
|
@lukaszsamson I am agreed with you. I don't see a reason we can't format regardless of the CWD. Since we have the project dir we can always use that to find the relevant |
Can confirm that this is what we have experienced as well. Perhaps @axelson you could try using the absinthe-graphql/absinthe code base as an example? It's got quite a few files (248, 21k LOC) and test files (212, 19k LOC). Does elixir-ls compile the full code base before formatting? Does format on save format all files or just the one saved? |
I can repro more specifically by repeatedly changing and saving a file. Eventually it'll block with the notification that the file save action is waiting on Elixir LS to format*. In the Elixir LS logs I noticed this seemed to occur if I saved right after I saw this message:
During that time format/save doesn't complete until it finishes. It seems like this may correlate with saving while the workspace symbol update is in progress? If I make changes really quickly it seems like I can reproduce this in 0.5.0 too. I'm unclear why it's worse in 0.6.0 though. I noticed 0.6.0 bumps Elixir and Erlang, some change there? I didn't see anything obvious in the release notes of either of those though. Is indexing slower, and thus the problem more apparent? One way or another it seems odd that reindexing the workspace symbols is blocking the format operation. It seems like we'd want to avoid blocking a save operation at all costs. Is this something the Language Server spec imposes? Is something in indexing causing the formatter to have to wait? I'm not sure when I'll next have a chance to look into this deeply, but hopefully this helps. * If I go really fast I get a different error that feels like another issue to address at a later date:
|
@axelson - Should I close this or would you like it to remain open? I don't want to mess with your workflow. |
I want to do some more testing and collect more feedback before closing this. Also ideally we could change the code to not use |
Nice, good call 👍 |
When dealing with `.formatter.exs` files that are in subdirectories of the main project, the behaviour was incorrect: elixir-lsp#361 And also caused performance problems: elixir-lsp#381 A good example is a project I currently work on. We have a top-level `.formatter.exs`, as well as a `test/.formatter.exs`. The one in `test/` has the `:inputs` option set to `["**/*.{ex,exs}"]`. Before this commit, should_format?/3 would take this pattern and concatenate it with the project directory. This would result in Path.wildcard/2 globbing for all source files in the entire project, rather than just under test/. This causes formatting to take about 5 seconds on our project. This commit fixes the problem by taking the file to be formatted, and finding the `.formatter.exs` file that exists in the closest parent directory (so long as that directory is still within the project root). We then perform the Path.wildcard/2 relative to that directory. I’ve removed the hack that was in place to support umbrella projects, because this is a more general solution to the problem. On our project, I am now able to format a file in 100ms or so, which isn’t a bad speed-up!
I've proposed a partial fix for this problem in #609 (by also fixing a bug with how I plan to also propose a more general solution, but that will take a bit longer. In the mean time, please try out the changes above and let me know if you encounter any problems (other than performance) on your projects. |
When dealing with `.formatter.exs` files that are in subdirectories of the main project, the behaviour was incorrect: elixir-lsp#361 And also caused performance problems: elixir-lsp#381 A good example is a project I currently work on. We have a top-level `.formatter.exs`, as well as a `test/.formatter.exs`. The one in `test/` has the `:inputs` option set to `["**/*.{ex,exs}"]`. Before this commit, should_format?/3 would take this pattern and concatenate it with the project directory. This would result in Path.wildcard/2 globbing for all source files in the entire project, rather than just under test/. This causes formatting to take about 5 seconds on our project. This commit fixes the problem by taking the file to be formatted, and finding the `.formatter.exs` file that exists in the closest parent directory (so long as that directory is still within the project root). We then perform the Path.wildcard/2 relative to that directory. I’ve removed the hack that was in place to support umbrella projects, because this is a more general solution to the problem. On our project, I am now able to format a file in 100ms or so, which isn’t a bad speed-up!
The call to Path.wildcard/2 can cause use to traverse a large number of files, which can be very slow depending on the project and the globs used: elixir-lsp#381 I wrote a library that implements a glob parser and allows us to check whether a glob matches a path without touching the filesystem: https://github.com/jonleighton/path_glob This commit switches out the Path.wildcard/2 call to use this library.
…ries (#609) * Convert should_format? test to use format/3 and fixtures This function is really an implementation detail, so let’s test the public API. The function also relies on interaction with the filesystem, so testing without fixtures is a bad idea because it will lead to incorrect results. * Check .formatter.exs :inputs relative to its directory When dealing with `.formatter.exs` files that are in subdirectories of the main project, the behaviour was incorrect: #361 And also caused performance problems: #381 A good example is a project I currently work on. We have a top-level `.formatter.exs`, as well as a `test/.formatter.exs`. The one in `test/` has the `:inputs` option set to `["**/*.{ex,exs}"]`. Before this commit, should_format?/3 would take this pattern and concatenate it with the project directory. This would result in Path.wildcard/2 globbing for all source files in the entire project, rather than just under test/. This causes formatting to take about 5 seconds on our project. This commit fixes the problem by taking the file to be formatted, and finding the `.formatter.exs` file that exists in the closest parent directory (so long as that directory is still within the project root). We then perform the Path.wildcard/2 relative to that directory. I’ve removed the hack that was in place to support umbrella projects, because this is a more general solution to the problem. On our project, I am now able to format a file in 100ms or so, which isn’t a bad speed-up! * Avoid costly Path.wildcard/2 call The call to Path.wildcard/2 can cause use to traverse a large number of files, which can be very slow depending on the project and the globs used: #381 I wrote a library that implements a glob parser and allows us to check whether a glob matches a path without touching the filesystem: https://github.com/jonleighton/path_glob This commit switches out the Path.wildcard/2 call to use this library. Co-authored-by: Jason Axelson <[email protected]>
That’s amazing! 🎉
On December 4, 2021, GitHub ***@***.***> wrote:
#609 <#609> was expanded
to fix this issue completely since with that change, ElixirLS no
longer requires a call to Path.wildcard/2 for formatting now that
PathGlob <https://github.com/jonleighton/path_glob> is used instead 🎊
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#381 (comment)-
986160421>, or unsubscribe
<https://github.com/notifications/unsubscribe-
auth/AAANRJSMRTYEYQB23ERA4W3UPLM75ANCNFSM4SL6QKNQ>.
|
Editing a simple
.exs
test file (340 lines) is taking around 3 seconds to format on save with no other edited files. I get a loading bar and a notification at bottom right mentioning the"ElixirLS: Elixir support and debugger"
formatter running.I installed 0.5.0 manually from the vsix and the problem is gone, so it looks like a regression in the latest release.
Any guesses on what happened between versions? Any particular logs or other diagnostic information can I provide to help debug?
This is an umbrella project of a fair size. Pure Elixir, so no large node_modules directories, etc.
Possible relation to #378?
Environment
Troubleshooting
.elixir_ls
directory, then restart your editorLogs
Wasn't sure exactly what to provide in this case but happy to include what I can.
The text was updated successfully, but these errors were encountered: