Repository navigation
perf(treesitter): cache skip nodes while searching for a match - #454
Open
Sciencentistguy wants to merge 1 commit into
Open
Sciencentistguy wants to merge 1 commit into
Sciencentistguy wants to merge 1 commit into
Conversation
The skip expression is evaluated for every candidate delimiter while searching for a match, and each evaluation ran the matchup query over `g:matchup_treesitter_stopline` lines either side of the cursor to rebuild the same set of skip nodes. With a `%` over a ~90 line rust function this was 75 queries and ~150ms, which is also paid by the matchparen highlight on every cursor movement. Keep the last result and reuse it while the buffer's changedtick, the language and query at the cursor and the rows around the cursor that were queried are all unchanged. Move the calculation of the queried rows into `internal.get_query_range()` so both places agree on it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
%is slow in treesitter buffers. In a ~90 line rust function,%plus the matchparen redraw takes ~213 ms.The skip expression runs for every candidate delimiter while searching for a match, and each call to
syntax.get_skips()re-runs the matchup query overg:matchup_treesitter_stoplinelines either side of the cursor to rebuild the same set of skip nodes. For that function that's 75 queries per%, and the matchparen highlight pays the same cost on every cursor movement.get_skips()now keeps the last result and reuses it while the buffer's changedtick, the language and query at the cursor, and the queried rows around the cursor are all unchanged. The row calculation moves tointernal.get_query_range()soget_matches()and the cache share it.For that rust function, on my machine, Neovim 0.12.6, one
%+ redraw + cursor-move cycle goes from 212.7 ms on master to 25.6 ms with this change.I added a test in
test/new/test-treesitter/test.vimthat counts query runs and checks the cache is reused and invalidated by moving out of the cached rows, editing the buffer and changing the query. It fails without the change. Thetest/newsuites that run directly withnvim -u test.vimpass and luacheck is clean; I haven't run the vader suite, vint, or Neovim 0.11.2.