company-sourcekit icon indicating copy to clipboard operation
company-sourcekit copied to clipboard

Improve the performance and accuracy

Open galeo opened this issue 8 years ago • 12 comments

I don't know if the development of this package is stopped. The last commit date on master branch was 7 months ago (Jun 5, 2016). Is there a change to improve the performance and accuracy?

There is a NeoVim plugin called Autocomplete-swift, which just uses SourceKitten as its back-end. When I tried to code with company-sourcekit(latest) in emacs(25.1.1) like the gif screenshot in its README, it went to totally mass.

screen shot 2017-01-06 at 10 01 44 pm As the above picture shows, when type var|, the completion list appeared, then type SPACE, it got completed like this: screen shot 2017-01-06 at 10 05 54 pm

Going on, type String|, screen shot 2017-01-06 at 10 06 32 pm then type SPACE, got this screen shot 2017-01-06 at 10 06 54 pm

... ...

I use the latest SourceKittenDaemon code compiled with Sourcekitten 0.15.0 and Xcode 8.2 a few days ago.


It seems that SourceKittenDaemon is not actively developed either, will it improve the performance and accuracy by just using SourceKitten as the back-end?

Or could we port Autocomplete-swift into emacs?

Thanks.

galeo avatar Jan 06 '17 14:01 galeo

I don't know if the development of this package is stopped. The last commit date on master branch was 7 months ago (Jun 5, 2016). Is there a change to improve the performance and accuracy?

It hasn't stopped, I am still using this package - I've just been satisfied with the results/performance.

It seems that SourceKittenDaemon is not actively developed either, will it improve the performance and accuracy by just using SourceKitten as the back-end?

SourceKittenDaemon does use SourceKitten as the backend, @mitsuse would be great to have your input here on the decision not to use SourcekittenDaemon and how you achieved the performance of your neovim package =D

Or could we port Autocomplete-swift into emacs?

You're more than welcome to :) If it turns out to be better I will probably switch as well. I don't think it's very feasible for company-sourcekit to switch from using SourceKittenDaemon since it will pretty much surmount to a re-write. Also, performance could be a matter of upgrading SourceKitten but looking at their changelog doesn't seem like there are any performance improvements to completion.

nathankot avatar Jan 06 '17 22:01 nathankot

The 400k+ issue is still occurred often with endless output writing to sourcekit-output-buffer and the completion results are often not accurate or relevant. It seems that there is still no progress made in completing middle of word (#19).

At first, I think we should compare this package with Autocomplete-swift to find out what we could achieve to improve the results/performance. @mitsuse is appropriate and welcome to do this.

I will try to make an experiment on using SourceKitten as the back-end a few days later. And I'm glad to see continuous improvement aiming at results/performance and more people are joined to make a contribution :)

galeo avatar Jan 07 '17 04:01 galeo

@galeo Hi.

I don't know the implementation of company-sourcekit and whether there are problems on performance, but I can tell about the implementation of autocomplete-swift on the point of completion accuracy. My plugin for Neovim decides the offset of completion as follow:

  • Trigger completion if the string matches a regular expression from the beginning of the current line to the cursor.
  • Calculate the byte-offset for completion

The second one seems to be related to this issue.

In addition, I think the difference of back-end (SourceKitten or SourceKittenDaemon) is not related to accuracy discussed here as long as I read the source of SourceKittenDaemon few months ago. @nathankot knows this point more than I know because he is a developer of SourceKittenDaemon.

mitsuse avatar Jan 07 '17 12:01 mitsuse

I'm really excited to see an issue like this. I'd love to get more info from @nathankot on what can be done to improve performance.

From what I've read it seems like the only way we can get close/improve on Xcode is by caching results from sourcekit? Maybe sourcekittendaemon would be a good place to add that layer? What are your thoughts @nathankot ? I've been casually researching this for a few days.

Some things I found which may (or may not) be useful:

This stuff is a bit over my head - I've never taken a compiler course, etc. But I'd love to help work on this and it looks like other people are interested too!

rudedogg avatar Jan 15 '17 16:01 rudedogg

@mitsuse

Thanks for your insight, I've added a28ac4811fac929686aca6aa6976845c02d6efd3 which addresses the byte-offset (wasn't using byte length of the prefix.)

@galeo @rudedogg

I did some digging and it seems like the biggest bottleneck for company-sourcekit is actually the http response results being written into the *sourcekit-output* buffer. It takes a good ~2 seconds for 3k lines of output.

Writing response results to a buffer is inevitable in emacs I think, so the question becomes - how do we speed this up? I'm working on a new branch performance trying things like disabling font-lock-mode, so far results don't seem significantly faster. Will look more into it tomorrow, but feel free to take a stab at this.

I would say the second priority here would be to cache word and framework completions, you're right @rudedogg this could be a sourcekittendaemon layer. Depending on how fast we can get the output and JSON parse it, this may or may not be necessary :)

nathankot avatar Jan 16 '17 00:01 nathankot

Hi @nathankot,

I have tried to use deferred.el to get the query results asynchronously. It just works well and the *sourcekit-output* buffer becomes useless. As you said above, the performance seems to be improved a little. I will submit a pull request later and you can have a test.

galeo avatar Jan 16 '17 01:01 galeo

@galeo not sure how much deferred.el will help since it also outputs to a buffer internally: https://github.com/kiwanami/emacs-deferred/blob/9668749635472a63e7a9282e2124325405199b79/deferred.el#L788

But send in the PR and I can take a look :)

nathankot avatar Jan 16 '17 01:01 nathankot

Please have a look at the PR #25 :)

galeo avatar Jan 16 '17 16:01 galeo

@galeo I've taken another look and refactored the code, fixed a few things that will hopefully help with performance. Please see the 0.2.0 release notes for full details - and let me know how it goes :)

nathankot avatar Jan 26 '17 11:01 nathankot

Hi @nathankot

I pulled the latest code and it works well except when it tries to send the first query request to SourceKittenDaemon, it outputs the following messages:

Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8081/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8082/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8083/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8084/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8085/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8086/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8087/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8088/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8089/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8090/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8081/ping.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8081/project.
Blocking call to accept-process-output with quit inhibited!!
REQUEST [error] Error (error) while connecting to http://localhost:8082/project.
Blocking call to accept-process-output with quit inhibited!! [2 times]
REQUEST [error] Error (error) while connecting to http://localhost:8083/project.
Blocking call to accept-process-output with quit inhibited!!
REQUEST [error] Error (error) while connecting to http://localhost:8084/project.
Blocking call to accept-process-output with quit inhibited!!
REQUEST [error] Error (error) while connecting to http://localhost:8085/project.
Blocking call to accept-process-output with quit inhibited!!
REQUEST [error] Error (error) while connecting to http://localhost:8086/project.
Blocking call to accept-process-output with quit inhibited!!
REQUEST [error] Error (error) while connecting to http://localhost:8087/project.
Blocking call to accept-process-output with quit inhibited!!
REQUEST [error] Error (error) while connecting to http://localhost:8088/project.
Blocking call to accept-process-output with quit inhibited!!
REQUEST [error] Error (error) while connecting to http://localhost:8089/project.
Blocking call to accept-process-output with quit inhibited!!
REQUEST [error] Error (error) while connecting to http://localhost:8090/project.

And I personally think the message [sourcekit] got query response should better be silenced when sourcekit-verbose is nil.

Another problem I noticed recently: when typed fast, it may establish lots of query requests and it suffers a serious delay to get the response results. screen shot 2017-01-26 at 9 52 57 pm

I experimented to improve the accuracy by tweaking the prefix and making company-sourcekit work with other backends, eg. company-keywords, company-yasnippet etc. I don't have enough time on this and there is only a little progress. The query results should better be filtered and cached with a flexible and robust mechanism. I see you've added a string match filter to the query result and it could be a good beginning. Thanks :)

galeo avatar Jan 26 '17 15:01 galeo

@galeo did you achieve any progress with this?

Pitometsu avatar May 04 '17 10:05 Pitometsu

Depending on how fast we can get the output and JSON parse it, this may or may not be necessary :)

Emacs master now has JSON encoding in C by the way. Not sure how much it'll help this problem.

jojojames avatar Dec 31 '17 18:12 jojojames