The Wayback Machine - https://web.archive.org/web/20221207062820/https://github.com/atom/autocomplete-plus/pull/672
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign SymbolStore and SymbolProvider #672

Merged
merged 17 commits into from Feb 21, 2016

Conversation

as-cii
Copy link
Contributor

@as-cii as-cii commented Feb 15, 2016

This PR changes SymbolStore and SymbolProvider so that they're faster when retrieving suggestions and when computing symbols.

Before

The way those two objects previously worked relied on storing symbols and the buffer rows they were contained in: this was a problem in a number of ways, especially after buffer changes where we had to scan through all those symbols to adjust their position according to the aforementioned change (in addition, we were doing this synchronously, blocking the UI thread until we scanned all the symbols).

screen shot 2016-02-15 at 16 44 25

(~ 350ms, benchmarks performed by writing 3 letters with 500 cursors)

Also, searching into SymbolStore involved a series of queries to selectorMatchesScopeChain which caused some major slowdowns every time SymbolProvider.prototype.getSuggestions() got called.

screen shot 2016-02-15 at 16 47 08

(~ 150ms, benchmarks performed by searching for cor in benchmark/large.js)

After

With this PR we're changing the way we store symbols (avoiding to index them by buffer row) and computing/scoring suggestions (e.g. locality score, fuzzy score, etc.) as we traverse through lines. This allows us to perform a very minimal bookkeeping on each buffer change while still being fast when retrieving possible autocompletions. Moreover, we now make use of TextBuffer.prototype.onDidStopChanging, so that writing one or ten letters in a row doesn't cause the main thread to stall.

This is how symbols re-computation looks like after these changes:

screen shot 2016-02-15 at 16 44 40

(~ 46ms, 8x faster 馃悗)

When storing tokens, we keep an index of symbols by letter for each buffer row. When retrieving them, we exploit the fact that a symbol needs to start with the prefix's first letter and, therefore, we score only tokens that match that first character.

screen shot 2016-02-15 at 17 00 02

(~ 53ms, 3x faster 馃悗)

Storing that index on a per-row basis has the advantage of not requiring us to deal with the "moving nature" of buffer rows, but forces us to iterate over every single line. Ideally here we may want to build a smarter data structure (i.e. a tree) that indexes letters across rows; on the other hand, though, the array-based implementation has pretty decent performance, and I believe we can avoid the added complexity of introducing an extra data structure for the time being.

Conclusion

Overall, this should allow us to take autocomplete-plus out of the multi-cursor slowness equation. I still feel like there's room for improvement (e.g. see the across rows index mentioned in the previous section) but I think this should allow us to move forward and deal with other bottlenecks in packages and tokenization.

/cc: @nathansobo @maxbrunsfeld @benogle for 馃憖

{Selector} = require 'selector-kit'
SymbolStore = require './symbol-store'

# TODO: remove this when `onDidStopChanging(changes)` ships on stable.
bufferSupportsStopChanging = -> typeof TextBuffer::onDidChangeText is "function"
Copy link
Contributor Author

@as-cii as-cii Feb 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am testing for the presence of onDidChangeText here because I couldn't find any other efficient heuristic to determine whether or not atom/text-buffer#126 shipped. This is temporary, though, so it might not be that important.

as-cii added a commit that referenced this pull request Feb 21, 2016
@as-cii as-cii merged commit f0602b1 into master Feb 21, 2016
0 of 3 checks passed
@as-cii as-cii deleted the as-redesign-symbol-store-provider branch Feb 21, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant