favadi / flycheck-gometalinter

Flycheck checker for gometalinter
BSD 2-Clause "Simplified" License
57 stars 8 forks source link

Huge slowdowns when typing #5

Closed dsvensson closed 7 years ago

dsvensson commented 7 years ago

When enabling flycheck-gometalinter I get excellent error reporting. The downside is that I experience severe lags when writing new code. I've tried creating a minimal emacs config with only go-mode and flycheck-gometalinter to rule out any other elisp package conflicting with this setup, and I still have the slowdowns. I'm using the default settings for flycheck-gometalinter, all checkers installed, go 1.8beta2, emacs 25.1.1, on Mac OS X 10.12.2 on a 2016 MBP, latest release of both flycheck-gometalinter and flycheck. Also tried upgrading flycheck to latest from git as there was a commit that tried to improve performance, but it didn't help out with this. An example file that will cause lagged down typing on my laptop is this one for example:

https://github.com/dsvensson/go-xmmsclient/blob/master/xmmsclient/serialize.go

Any suggestions to what to check?

favadi commented 7 years ago

It sounds like a problem with gometalinter, not flycheck. Can you try (setq flycheck-gometalinter-fast t)? It will disable some slow checkers and likely improve performance.

dsvensson commented 7 years ago

Then it's fast, but then it runs with fewer checkers. I might have misunderstood flycheck, but aren't checkers executed async? I wouldn't have any problem if a checker result were delayed 10 seconds, or even more than a minute, as long as writing code wasn't affected, but if flycheck is indeed synchronous, than I understand why it becomes slow. :/

Here's gometalinter without --fast:

$ time ~/.emacs.d/go-utils/bin/gometalinter xmmsclient > /dev/null
  10,28s user 3,28s system 621% cpu 2,182 total

Although I don't experience any 3 second stalls when typing, it's just that it's constantly kind of slow, perhaps somewhere between 0.5-1 seconds stalls, and lots of them (hard to guesstimate).

dsvensson commented 7 years ago

This lag seems to be caused by an number of factors. First of all I hadn't customized flycheck-idle-change-delay so it was executing after 0.5 seconds timeout since last modification, which might happen when I write code and think about what to write next. When this happens two things seem to slowdown Emacs. First gometalinter runs by default with a concurrency level of 16. This steals CPU-time from the editor as I only have 8 cores. Secondly, when the gometalinter process exits and emacs have to parse its output, there's a decent stall. It's proably a better idea to try to integrate the different checkers in flycheck directly, so that flycheck fills the role of gometalinter. That way the checkers are run separatly, and it's less output to parse each time. Finally when trying to figure out why it was slow, I held the return-key, and that ofc triggered flycheck as I hadn't customized flycheck-check-syntax-automatically to only trigger on idle-change and mode-enabled.

favadi commented 7 years ago

I have (setq flycheck-check-syntax-automatically '(mode-enabled save)) in init.el so flycheck only runs on save. I'm not sure if I can do anything to improve the situation.

dsvensson commented 7 years ago

I think there are a number of ways to improve the situation:

dsvensson commented 7 years ago

Added concurrency option in https://github.com/favadi/flycheck-gometalinter/pull/6

favadi commented 7 years ago

I merged #6.

favadi commented 7 years ago

@dsvensson your MR is merged, should we close this issue?

dsvensson commented 7 years ago

The biggest pain was from system wide resource starvation. I think the current slowdowns are due to all checkers running at once and yielding a very big message to parse, rather than running each checker after each other like flycheck otherwise does.