From: Yuan Fu <casouri@gmail.com>
To: Dmitry Gutov <dgutov@yandex.ru>
Cc: 61285@debbugs.gnu.org
Subject: bug#61285: (Sometimes very) slow font-lock after %w in ruby-ts-mode
Date: Sun, 5 Feb 2023 16:08:36 -0800 [thread overview]
Message-ID: <2C6F83F0-DD84-4549-9D91-3D820188674D@gmail.com> (raw)
In-Reply-To: <17a29b2e-beb2-f246-fe1c-2c3503c1bfe6@yandex.ru>
Dmitry Gutov <dgutov@yandex.ru> writes:
> This probably involves a parser bug and/or maybe a tree-sitter one.
> But I'm posting this here anyway because this might not be the only
> way to trigger this problem. Or it could give us some optimization
> insights.
>
> Also, while it involves a node which is parsed to have a large number
> of descendants, the performance depends heavily on whether the node is
> at the top level of the program (then it's slow), or not.
>
> To repro:
>
> 1. Visit test/lisp/progmodes/ruby-mode-resources/ruby.rb
> 2. add 'a = %w' (without quotes) as a separate new line before all of
> the existing code.
> 3. Notice the delay in redisplay after you type 'w'.
>
> In you do that with a larger file, BTW, this delay may be on the order
> of a minute. Here's an example of such file:
> https://github.com/rails/rails/blob/main/activerecord/lib/active_record/associations.rb
>
> The superficial reason for this delay is that %w opens a new "array of
> strings" literal which parses every separate word in the rest of the
> buffer as a separate string. So we get a node with thousands of
> children, in the case of associations.rb. Or just ~1000 in the case of
> ruby.rb.
>
> I also tried setting treesit--font-lock-fast-mode to t: no effect.
>
> But! If we do the same not on top-level -- say, put the 'a = %w' line
> after the 'foo' line inside the first 'if' statement (i.e. on line 7),
> the delay is much smaller -- not noticeable in ruby.rb, and still
> apparent but much more bearable in associations.rb (you can put that
> statement right after 'module ActiveRecord') -- even though the size
> of the tree is changed minimally, and the number of children nodes for
> that "array of strings" still counts in the thousands (e.g. 13319).
>
> Perf report for the "bad" highlighting delay looks like this:
>
> 61.19% emacs libtree-sitter.so.0.0 [.] ts_tree_cursor_current_status
> 30.88% emacs libtree-sitter.so.0.0 [.] ts_tree_cursor_parent_node
> 7.44% emacs libtree-sitter.so.0.0 [.] ts_language_symbol_metadata
> 0.06% emacs libtree-sitter.so.0.0 [.] ts_tree_cursor_goto_first_child
> 0.05% emacs libtree-sitter.so.0.0 [.] ts_tree_cursor_goto_next_sibling
> 0.03% emacs libtree-sitter.so.0.0 [.] ts_node_end_byte
>
> And like this in the "good" case (with many type-backspace repetitions):
>
> 32.10% emacs libtree-sitter.so.0.0 [.] ts_tree_cursor_current_status
> 9.50% emacs libtree-sitter.so.0.0 [.] ts_tree_cursor_goto_first_child
> 7.89% emacs libtree-sitter.so.0.0 [.] ts_tree_cursor_goto_next_sibling
> 7.51% emacs libtree-sitter.so.0.0 [.] ts_language_symbol_metadata
> 6.45% emacs libtree-sitter.so.0.0 [.] ts_tree_cursor_parent_node
> 1.87% emacs libtree-sitter.so.0.0 [.] ts_node_start_point
> 1.85% emacs emacs [.] process_mark_stack
> 0.93% emacs libtree-sitter.so.0.0 [.] ts_tree_cursor_current_node
Interesting. Perhaps it has to do with how tree-sitter implements the
"incremental" part of the parser? But the profile doesn’t look like it’s
spending time parsing, I need to look at what does
ts_tree_cursor_current_status actually do (maybe it’s used in parsing?)
Yuan
next prev parent reply other threads:[~2023-02-06 0:08 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-05 0:39 bug#61285: (Sometimes very) slow font-lock after %w in ruby-ts-mode Dmitry Gutov
2023-02-06 0:08 ` Yuan Fu [this message]
2023-02-06 1:03 ` Dmitry Gutov
2023-02-06 3:20 ` Dmitry Gutov
2023-02-21 3:12 ` Dmitry Gutov
2023-02-21 8:14 ` Yuan Fu
2023-02-21 9:53 ` Dmitry Gutov
2023-02-27 0:37 ` Yuan Fu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2C6F83F0-DD84-4549-9D91-3D820188674D@gmail.com \
--to=casouri@gmail.com \
--cc=61285@debbugs.gnu.org \
--cc=dgutov@yandex.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).