Subject: bug#69071: Emacs master branch: c-ts-mode is slow with large C functions.

From: Yuan Fu <[email-masked]>
Date: Mon, 19 Feb 2024 21:49:26 -0800

> On Feb 15, 2024, at 8:06 PM, Yuan Fu <[email-masked]> wrote:
> 
> 
> 
>> On Feb 15, 2024, at 12:36 AM, Eli Zaretskii <[email-masked]> wrote:
>> 
>>> Date: Mon, 12 Feb 2024 11:30:00 +0000
>>> From: Alan Mackenzie <[email-masked]>
>>> 
>>> Using Emacs master:
>>> 
>>> c-ts-mode is slow on large C functions when editing towards the end of
>>> such a function.
>>> 
>>> As an extreme example, there is a function proto_register_rrc in the
>>> file packet-rrc.c which is part of Wireshark.  This file is "available"
>>> from Github, but sadly no longer freely available - you need to allow
>>> Microsoft's scripts to run on your machine.  I'm willing to send this
>>> file by email to anybody who needs it.  It is almost 10 MB in size.
>>> 
>>> proto_register_rrc is around 50,000 lines long, total size about 2¼ MB.
>>> 
>>> Near the end of the function, after typing a character, there is a delay
>>> of between 9 and 10 seconds (on my 7 year old machine) before redisplay
>>> happens.  This is too long.  Some optimisation seems needed.
>>> 
>>> On disabling font-lock-mode, the response becomes instantaneous.
>> 
>> Yuan, could you please look into this?
> 
> Oops, didn’t see this. I’ll take a look.

Before we continue, let me note that this seems like another case where tree-sitter-c parser chokes on some extreme C code. Profiler reports shows that almost all time are spent in treesit-parser-root-node, which indicates that all the time are spent parsing the text.

Yuan

        6094  61% - ...
        5542  55%  - self-insert-command
        5542  55%   - electric-indent-post-self-insert-function
        5542  55%    - indent-according-to-mode
        5542  55%     - treesit-indent
        5542  55%      - let*
        5542  55%       - treesit--indent-1
        5542  55%        - let*
        5542  55%         - cond
        5542  55%          - treesit-node-at
        5542  55%           - let*
        5542  55%            - if
        5542  55%             - or
        5542  55%              - treesit-buffer-root-node
        5542  55%               - let*
        5542  55%                - if
        5542  55%                   treesit-parser-root-node
         552   5%  + #<compiled 0x1812af33e570332e>
        3834  38% - redisplay_internal (C function)
        3824  38%  - redisplay--pre-redisplay-functions
        3824  38%   - run-hook-with-args
        3824  38%    - treesit--pre-redisplay
        3824  38%     - if
        3824  38%      - let
        3824  38%       - while
        3824  38%        - let
        3824  38%           treesit-parser-root-node
           5   0% + command-execute
           5   0% + timer-event-handler