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

Opening largish files is crazy slow due to SMIE #463

Open
bitwalker opened this issue Oct 1, 2020 · 6 comments
Open

Opening largish files is crazy slow due to SMIE #463

bitwalker opened this issue Oct 1, 2020 · 6 comments

Comments

@bitwalker
Copy link

I have an Elixir file with ~4k lines in it, more than a few of them actually - and every time I open them, it takes ~10-20 seconds for the file to open. Its honestly driving me nuts.

I ran the profiler to see what is going on, and it looks like the only thing taking any meaningful time at all is elixir-mode's use of SMIE, in particular the elixir-smie--semi-ends-match function and its use of looking-back. It so utterly dominates the samples in the profiler, that fixing this would completely fix the problem I'm seeing (and presumably others are seeing as well, its wild to me that this isn't reported already).

It seems to me that a much more efficient method than is currently used in elixir-smie--semi-ends-match should be possible, or at least use some heuristics to avoid backtracking nearly as much as it does currently. The documentation for looking-back specifically states to avoid using it wherever possible, and we're using it twice to first detect elixir-smie--block-operator-regexp but then reject .+fn.+. At a minimum it would be faster to add a specialized regex that does that match in one go. If I knew more about how all the pieces fit together, I'd take a stab at rewriting it, but wanted to get some feedback first. Have you seen this issue? If so, how have you handled it in your own config?

@axelson
Copy link
Contributor

axelson commented Oct 3, 2020

I have noticed this too, and we were having a discussion about it in #emacs on the Elixir Slack the other day. Some improvements to the performance of the syntax detection would be very welcome.

@victorolinasc
Copy link
Contributor

Hi @bitwalker ! It certainly can be improved... PRs are welcome! I myself haven had to deal with such a large file yet and I am running the native-comp branch currently so haven't seen this kind of slowdowns yet. Anyway I agree the current algorithm can be improved upon.

@lambdadog
Copy link

If anyone has an example of such a large elixir file that could be tested against, that might be helpful in addressing this issue.

@bitwalker
Copy link
Author

I can’t post the originals that trigger this in my work project, but I’ll put together a repro based on them and post back here.

In general though, you can probably also just take any typical Elixir module, clone the contents of it until you have at least a couple thousand lines of code, save it and reopen the file to reproduce. If you run the profiler you should observe an exponential increase in the time spent opening the buffer.

@maxlorenz
Copy link

maxlorenz commented Nov 17, 2020

You can simply do this:

iex(1)> {:ok, file} = File.open("demo.exs", [:write])
iex(2)> Enum.each(1..5000, fn _ -> IO.binwrite(file, "def sq(x), do: x * x\n") end)
iex(3)> File.close(file)

The resulting file will take ~20-30 seconds to open, vs ~1s for the same amount of lines of Python or Ruby on my machine

@axelson axelson pinned this issue Nov 28, 2020
J3RN pushed a commit to J3RN/emacs-elixir that referenced this issue Apr 24, 2021
* Fixes tests not compiling after first run

* Move temporary test files to elixir_ls_utils/.tmp

* Add newline at end of gitignore
J3RN pushed a commit to J3RN/emacs-elixir that referenced this issue Apr 24, 2021
After elixir-editors#463 was merged, there is nothing actually using the tmp directory
for tests. And any current contributors who pull down master will still
have the issue, so by removing `tmp` from .gitignore it is a signal to
contributors to clean up that directory (and then their tests will work
again).
@korsmakolnikov
Copy link

Up

axelson added a commit to axelson/emacs-elixir that referenced this issue Dec 19, 2021
This PR disables the worst offenders of lookbacks that make opening
large files very slow.

More testing is needed to determine if this is a worthwhile tradeoff.
The main reason it is palatable is that it fixes
elixir-editors#463 and
indentation isn't as important as it once was because you can simply run
`elixir-format` (or `lsp-format-buffer`).
@victorolinasc victorolinasc unpinned this issue Jun 12, 2023
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

6 participants