OmniSharp / omnisharp-roslyn

OmniSharp server (HTTP, STDIO) based on Roslyn workspaces
MIT License
1.78k stars 420 forks source link

Slow completion with EnableImportCompletion #2479

Open DencoL opened 1 year ago

DencoL commented 1 year ago

Hi, I have been using omnisharp-roslyn in neovim for a while now. I have noticed, that sometimes the completion is little bit slow. It takes a while to show the results. I have found out that it is because I have EnableImportCompletion set to true. Here is a little showcase:

EnableImportCompletion: true omnisharp-roslyn-with-auto-import

EnableImportCompletion: false omnisharp-roslyn-without-auto-import

As you can see in the first example, it takes a moment to get the completion. I have debuggged the code myself and what I can see is, that with EnableImportCompletion: true, it returns over 12 000 results. And then, my completion plugin has to handle that, which is probably the pain point here.

I know this might an issue for the completion plugin, but I wanted to try here first: Is there any way the completion result list could be reduced? It does contain results relevant to what I'm typing, but it also contains a lot of results totally irrelevant to what I'm typing.

lynzrand commented 1 year ago

Sorry for bumping this issue. I have experienced the same problem using VSCode Omnisharp within a Unity project. My completion returned around 11000 results.

However, I don't think the large amount of results is the one blocking here. I have profiled VSCode window and extension host, neither is blocking just to handle the results. However, the extension host is blocked on Interface._normalWritenode:readline, which I believe is it reading the result from Omnisharp. Since this issue occurs on two different platforms (vscode and neovim), it is probably because Omnisharp being too slow to generate the results.


The following is a profiling of VSCode extension host. The two big blocks in the image are the times when the plugin is blocking.

VSCode extension profiling

VSCode extension profiling, zoomed in

The extension host call stack looks like this:

Start Time Self Time Total Time Activity
5286.3 ms 0.0 ms 2790.1 ms Function Call  
5286.4 ms 0.0 ms 2790.1 ms onStreamRead node:internal/stream_base_commons:167:22  
5286.4 ms 0.0 ms 2790.1 ms Readable.push node:internal/streams/readable:227:35  
5286.4 ms 0.0 ms 2790.1 ms readableAddChunk node:internal/streams/readable:236:26  
5286.4 ms 0.0 ms 2790.1 ms addChunk node:internal/streams/readable:304:18  
5286.4 ms 0.0 ms 2790.1 ms emit node:events:460:44  
5286.4 ms 0.0 ms 2790.1 ms ondata node:readline:271:18  
5286.4 ms 2422.8 ms 2790.1 ms Interface._normalWrite node:readline:638:44
lucasfan110 commented 1 year ago

Any solutions to this?

lynzrand commented 1 year ago

Any solutions to this?

It would need more profiling of Omnisharp itself to determine which part of it slowed it down.

The easiest solution might be adding a new config key to limit imported results to appear only when e.g. more than 3 letters are typed. However, I haven't looked into Omnisharp's architecture so it may not work as I thought.

lynzrand commented 1 year ago

If I did the profiling right, there isn't any long-running computation blocking the completion (see CPU section below, when I triggered Omnisharp with two inputs that would block):

图片

Flame graph:

图片

I think it is an IO blocking issue. However, I don't know which part (omnisharp or extension server) is blocking.