fwcd / kotlin-language-server

Kotlin code completion, diagnostics and more for any editor/IDE using the Language Server Protocol
MIT License
1.62k stars 203 forks source link

Slow initialization #510

Open kohnish opened 11 months ago

kohnish commented 11 months ago

With eglot with GNU Emacs, you need to set something like (setq eglot-connect-timeout 999999) for kotlin-language-server. In case of this project, it takes about 5 minutes to initialize on my machine and then you can start using it.

In another private project in an offline environment, using a really powerful machine like a server with 40 cores doesn't seem to improve indexing speed either without utilising full cpu cores but that may be due to the specific project. But the pain is that it has to happen on every time you restart GNU Emacs.

Would it be possible to try to make it partially ready early and prioritise current request like clangd?

kohnish commented 10 months ago

It looks similar to this.
https://github.com/fwcd/kotlin-language-server/issues/301.

But the CPU isn't used at all and it seems to be happening sequentially.

:message "async0    Resolving dependencies for
themkat commented 10 months ago

This has been an issue for a while. Problem is that without an index, you will not be able to get any completion almost. This is due to the symbols not existing anywhere until the indexing is done.

I think our biggest hope of making this better is some sort of caching solution like #489. Then the "pain" will only be the first time you start the project, or when adding new dependencies. Feel free to test the PR and help us out if you have some extra time to try it! 😄 (also remember that giving the storage path during init is necessary to use the ondisk cache, see how Emacs lsp-mode does it for reference: https://github.com/emacs-lsp/lsp-mode/blob/master/clients/lsp-kotlin.el#L274 )

kohnish commented 10 months ago

Thanks for the reply @themkat . I'll give it a go and leave some remarks there.

@daplf mentions there should be more robust mechanism to update dependencies. Can we start brain storming this on this bit? I'm happy to help while on the journey to learn this language.
I'm especially sad about the fact that CPU is not utilised in my case, is it kotlin(gradle) dependency resolver limitation?

themkat commented 10 months ago

Thanks for the reply @themkat . I'll give it a go and leave some remarks there.

@daplf mentions there should be more robust mechanism to update dependencies. Can we start brain storming this on this bit? I'm happy to help while on the journey to learn this language. I'm especially sad about the fact that CPU is not utilised in my case, is it kotlin(gradle) dependency resolver limitation?

Feel free to share any ideas you may have! 😄 I'm unsure on how to solve it myself, and would love to see people share their ideas on how to solve the issue of a more robust mechanism to update dependencies. If you see any ways we could utilize CPU better (maybe we could be better at creating more threads if the user has a powerful CPU?), I would also LOVE to hear about that 🙂 The CPU utlization is an issue with both the Gradle resolver and with the number of threads we spawn to populate the index. I suspect we might be able to create more threads.

kohnish commented 10 months ago

Nice! Maybe it's an idea to first compare the dependency resolution speed with the bare gradle command and the language server, assuming gradle is the main thing responsible for dependency resolution.
Stop me if my assumption is wrong but apparently gradle dependencies or gradle app:dependencies is the command. I'll check it out later.

I may be too harsh on the performance as well, coming from using clangd. So this should also rule out if I'm just too impatient.

kohnish commented 10 months ago

gradle app:dependencies finishes within a minute with a project that takes more than 10 minutes for the initial dependency fetching with little cpu usage. The actual compilation of the project even takes less than 10 min.

I guess that means something can be drastically improved. For that I need to understand the code and try to identify the file or module causing the issue.

calamont commented 9 months ago

For me, the slow initialisation seems to be due to the LSP indexing all gradle dependincies on my system. If I create a small example project with gradle init, once the LSP is running, it generates autocomplete lists from dependencies that have not been installed in that project. Does that sound like the expected current behaviour?

I don't have this issue with jdtls so I presume its related to how Kotlin works with Gradle. I want to understand/fix this behaviour but have been quite busy recently.