emacs-lsp / lsp-mode

Emacs client/library for the Language Server Protocol
https://emacs-lsp.github.io/lsp-mode
GNU General Public License v3.0
4.75k stars 873 forks source link

Godot GDScript performance issues with lsp-mode #2886

Open NathanLovato opened 3 years ago

NathanLovato commented 3 years ago

When writing GDScript code with lsp-mode, errors keep appearing as you type and the autocompletion popup can take a lot of time to appear.

We did some troubleshooting thanks to @yyoncho on Discord.

What we tried:

This problem happens specifically in Emacs. There are two other GDScript LSP clients for Atom and VSCode which don't have these performance issues. Here's the VSCode client: https://github.com/godotengine/godot-vscode-plugin.

Steps to reproduce

Godot's GDScript is an embedded, domain-specific language. The language server runs when you open a project in the engine and its editor.

So you need to download and run Godot (no install required) to use the language server. You need to install gdscript-mode to add support for the GDScript programming language on Emacs's side. It's available on MELPA.

Emacs version: I could reproduce the issue with both Emacs 27.1 and an Emacs 28.0.50 with native compilation.

Reproduction steps:

The completion takes time to appear, and linter error messages get reported as you type (it can take some time for errors to appear).

timer-example

Expected behavior: the completion popup appears instantly and updates as you type.

More information about how Godot works

When coding from within the Godot editor, Godot has an idle time setting, after which it will recompile the script, set to 2 seconds by default.

The language requires recompiling a script to report errors and lint your code. Normally, this only happens when you pause and wait for the compiler to rerun.

Looking at the reported errors in Emacs, it looks like the language server is trying to constantly recompile the script as you type each character.

The thing that is strange is that it happens with LSP mode but not in VSCode or Atom, suggesting the issue could be linked to the client.

I'm at your disposal if you need any more information.

yyoncho commented 3 years ago

I tested with both my config and with vanilla and the whole compoletion process feels very lightweight and instant without slowdown or anything...

https://user-images.githubusercontent.com/13259670/119545646-b89fe800-bd9b-11eb-807a-4d4776d75b85.mp4

Can you test without lsp-ui?

yyoncho commented 3 years ago

can you also check if it reproduces with only one imported project?

Can you test with

  (setq create-lockfiles nil)
  (setq make-backup-files nil)
NathanLovato commented 3 years ago

Yes, I have the issue after removing all known lsp projects and importing just one. I also set the variables as requested.

The performance issues can really scale with the project and script. Sometimes it completes well for a few lines before the issue starts to appear.

Here's a recording working in a session with lsp-start-plain.el and on a much more complex project:

https://user-images.githubusercontent.com/12694995/119555513-2d066700-bd5b-11eb-8c59-0d598f4cb5f1.mp4

Please don't mind the shortcut errors as I don't know emacs's vanilla keybindings well.

You can find the project's repository here: https://github.com/GDQuest/godot-2d-tactical-space-combat

If you'd like to try it, you can open godot/TacticalSpaceCombat.gd in Emacs. You'll need to import and edit the godot/project.godot file in the Godot editor too.

yyoncho commented 3 years ago

Yes, I have the issue after removing all known lsp projects and importing just one. I also set the variables as requested.

Just to make sure that we are on the same page - I meant removing all projects from the server, not from lsp-mode.

Also, I do not see the warnings - are you using the latest godot server?

NathanLovato commented 3 years ago

Just to make sure that we are on the same page - I meant removing all projects from the server, not from lsp-mode.

I tried clearing all known Godot projects on Godot's side, along with the cache, same issue.

are you using the latest godot server?

Yes, running Godot 3.3.2 at the moment.

Is there anything else I can test for you?

yyoncho commented 3 years ago

Can you set lsp-print-io to t before starting the project and then collect the logs when performing the slow completion? (Just bear in mind that lsp-print-io = t will slow down lsp-mode even more).

yyoncho commented 3 years ago

I will try to implement the missing methods from gd server and also check the vscode client server logs.

NathanLovato commented 3 years ago

Thanks much. If you have any questions about the VSCode extension, you can ask my teammate @Razoric480 as he now maintains it. He also worked on fixing issues with the GDScript language server recently.

NathanLovato commented 3 years ago

Here is the log after a few moments typing (~10-15 seconds with pauses waiting for completion). It's really big, 18MB, so I zipped it.

lsp-log.zip

yyoncho commented 3 years ago

On my system I do not see any difference between vscode performance and emacs performance. lsp-start-plain.el is not a optimal configuration so it was bad idea to test performance with it(the slowdown might have been caused by bad gc-cons-treshold).

Can you try this config:

https://github.com/yyoncho/lsp-mode/commit/8967de8c18f9b60d562a5b43550fbcace6696e3f

Start it like this:

emacs -q -l gdscript.el

NathanLovato commented 3 years ago

Thanks, I just tested it and unfortunately it's still the same.

Note that I followed the docs and section on performance long before raising the issue. Actually, I've had the problem for over a year but just worked without lsp for Godot - the language server had its issues too.

yyoncho commented 3 years ago

I will create gitpod reproducer for this. I suspect that there is something in your env which is making client/server communication slow.