Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the performance and accuracy #24

Open
galeo opened this issue Jan 6, 2017 · 12 comments
Open

Improve the performance and accuracy #24

galeo opened this issue Jan 6, 2017 · 12 comments

Comments

@galeo
Copy link
Contributor

galeo commented Jan 6, 2017

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.

@nathankot
Copy link
Owner

nathankot commented Jan 6, 2017

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.

@galeo
Copy link
Contributor Author

galeo commented Jan 7, 2017

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 :)

@mitsuse
Copy link

mitsuse commented Jan 7, 2017

@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.

@rudedogg
Copy link

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!

@nathankot
Copy link
Owner

nathankot commented Jan 16, 2017

@mitsuse

Thanks for your insight, I've added a28ac48 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 :)

@galeo
Copy link
Contributor Author

galeo commented Jan 16, 2017

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.

@nathankot
Copy link
Owner

@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 :)

@galeo
Copy link
Contributor Author

galeo commented Jan 16, 2017

Please have a look at the PR #25 :)

@nathankot
Copy link
Owner

@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 :)

@galeo
Copy link
Contributor Author

galeo commented Jan 26, 2017

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 :)

@Pitometsu
Copy link

@galeo did you achieve any progress with this?

@jojojames
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants