Package: emacs;
Reported by: JD Smith <jdtsmith <at> gmail.com>
Date: Mon, 7 Apr 2025 21:50:02 UTC
Severity: normal
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 77620 in the body.
You can then email your comments to 77620 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
bug-gnu-emacs <at> gnu.org:bug#77620; Package emacs.
(Mon, 07 Apr 2025 21:50:02 GMT) Full text and rfc822 format available.JD Smith <jdtsmith <at> gmail.com>:bug-gnu-emacs <at> gnu.org.
(Mon, 07 Apr 2025 21:50:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: JD Smith <jdtsmith <at> gmail.com> To: bug-gnu-emacs <at> gnu.org Subject: thingatpt can be incredibly slow in python-mode buffers Date: Mon, 7 Apr 2025 17:48:49 -0400
[Message part 1 (text/plain, inline)]
As discussed in Bug#77588: > (/ (car (benchmark-run 10 (thing-at-point 'sexp))) 10) Try this test at the start of L8817 in this file (no eglot needed; either python-mode or python-ts-mode is fine, as both show the same issue): https://raw.githubusercontent.com/matplotlib/matplotlib/refs/heads/main/lib/matplotlib/axes/_axes.py https://raw.githubusercontent.com/matplotlib/matplotlib/refs/heads/main/lib/matplotlib/axes/_axes.py _axes Text Document · 353 KB In #77588 this was shown to lead to long intermittent pauses with eglot in large python buffers, but the issue is more general for any packages using thingatpt in python buffers.
[Message part 2 (text/html, inline)]
[preview.png (image/png, inline)]
bug-gnu-emacs <at> gnu.org:bug#77620; Package emacs.
(Tue, 08 Apr 2025 10:53:01 GMT) Full text and rfc822 format available.Message #8 received at 77620 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: JD Smith <jdtsmith <at> gmail.com>, kobarity <kobarity <at> gmail.com> Cc: 77620 <at> debbugs.gnu.org Subject: Re: bug#77620: thingatpt can be incredibly slow in python-mode buffers Date: Tue, 08 Apr 2025 13:52:44 +0300
> From: JD Smith <jdtsmith <at> gmail.com>
> Date: Mon, 7 Apr 2025 17:48:49 -0400
>
> > (/ (car (benchmark-run 10 (thing-at-point 'sexp))) 10)
>
>
> Try this test at the start of L8817 in this file (no eglot needed; either python-mode or python-ts-mode is fine, as both show the same issue):
>
> https://raw.githubusercontent.com/matplotlib/matplotlib/refs/heads/main/lib/matplotlib/axes/_axes.py
> https://raw.githubusercontent.com/matplotlib/matplotlib/refs/heads/main/lib/matplotlib/axes/_axes.py
> _axes
> Text Document · 353 KB
>
> In #77588 this was shown to lead to long intermittent pauses with eglot in large python buffers, but the issue is more general for any packages using thingatpt in python buffers.
The Lisp profile, which seems to point to the likely culprit, is
below.
Maybe kobarity (CC'ed) will have some ideas or suggestions.
345 89% - ...
343 89% - cond
343 89% - let
343 89% - condition-case
343 89% - progn
343 89% - save-excursion
173 44% - funcall
173 44% - thing-at-point--end-of-sexp
173 44% - let
173 44% - if
173 44% - condition-case
173 44% - forward-sexp
173 44% - python-nav-forward-sexp
173 44% - python-nav--forward-sexp
173 44% - python-info-statement-ends-block-p
173 44% - python-nav-end-of-block
96 24% - python-nav-end-of-statement
69 17% - syntax-ppss
67 17% parse-partial-sexp
27 7% - python-info-line-ends-backslash-p
27 7% - syntax-ppss
27 7% parse-partial-sexp
76 19% - python-nav-beginning-of-block
76 19% - python-nav-backward-block
76 19% - python-nav-forward-block
75 19% - python-syntax-context-type
75 19% - syntax-ppss
74 19% parse-partial-sexp
1 0% - python-nav-beginning-of-statement
1 0% point-marker
1 0% current-indentation
170 44% - let
170 44% - if
170 44% - funcall
170 44% - thing-at-point--beginning-of-sexp
170 44% - let
170 44% - if
170 44% - forward-sexp
170 44% - python-nav-forward-sexp
170 44% - python-nav--forward-sexp
170 44% - python-info-statement-ends-block-p
170 44% - python-nav-end-of-block
95 24% - python-nav-end-of-statement
63 16% - syntax-ppss
62 16% parse-partial-sexp
31 8% - python-info-line-ends-backslash-p
31 8% - syntax-ppss
30 7% parse-partial-sexp
1 0% re-search-forward
75 19% - python-nav-beginning-of-block
75 19% - python-nav-backward-block
75 19% - python-nav-forward-block
72 18% - python-syntax-context-type
72 18% - syntax-ppss
71 18% parse-partial-sexp
2 0% re-search-backward
1 0% - python-nav-beginning-of-statement
1 0% - python-info-line-ends-backslash-p
1 0% - syntax-ppss
1 0% syntax-ppss--data
2 0% - python-shell-get-process
2 0% - python-shell-get-buffer
2 0% - seq-some
2 0% + seq-do
32 8% Automatic GC
6 1% - command-execute
6 1% - call-interactively
6 1% - byte-code
6 1% - read-extended-command
6 1% - read-extended-command-1
6 1% - completing-read
6 1% - completing-read-default
6 1% - read-from-minibuffer
1 0% redisplay_internal (C function)
2 0% redisplay_internal (C function)
bug-gnu-emacs <at> gnu.org:bug#77620; Package emacs.
(Wed, 09 Apr 2025 15:34:02 GMT) Full text and rfc822 format available.Message #11 received at 77620 <at> debbugs.gnu.org (full text, mbox):
From: kobarity <kobarity <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 77620 <at> debbugs.gnu.org, JD Smith <jdtsmith <at> gmail.com> Subject: Re: bug#77620: thingatpt can be incredibly slow in python-mode buffers Date: Thu, 10 Apr 2025 00:33:03 +0900
Eli Zaretskii wrote: > > > From: JD Smith <jdtsmith <at> gmail.com> > > Date: Mon, 7 Apr 2025 17:48:49 -0400 > > > > > (/ (car (benchmark-run 10 (thing-at-point 'sexp))) 10) > > > > > > Try this test at the start of L8817 in this file (no eglot needed; either python-mode or python-ts-mode is fine, as both show the same issue): > > > > https://raw.githubusercontent.com/matplotlib/matplotlib/refs/heads/main/lib/matplotlib/axes/_axes.py > > https://raw.githubusercontent.com/matplotlib/matplotlib/refs/heads/main/lib/matplotlib/axes/_axes.py > > _axes > > Text Document · 353 KB > > > > In #77588 this was shown to lead to long intermittent pauses with eglot in large python buffers, but the issue is more general for any packages using thingatpt in python buffers. > > The Lisp profile, which seems to point to the likely culprit, is > below. > > Maybe kobarity (CC'ed) will have some ideas or suggestions. > > 345 89% - ... > 343 89% - cond > 343 89% - let > 343 89% - condition-case > 343 89% - progn > 343 89% - save-excursion > 173 44% - funcall > 173 44% - thing-at-point--end-of-sexp > 173 44% - let > 173 44% - if > 173 44% - condition-case > 173 44% - forward-sexp > 173 44% - python-nav-forward-sexp > 173 44% - python-nav--forward-sexp > 173 44% - python-info-statement-ends-block-p > 173 44% - python-nav-end-of-block > 96 24% - python-nav-end-of-statement > 69 17% - syntax-ppss > 67 17% parse-partial-sexp > 27 7% - python-info-line-ends-backslash-p > 27 7% - syntax-ppss > 27 7% parse-partial-sexp > 76 19% - python-nav-beginning-of-block > 76 19% - python-nav-backward-block > 76 19% - python-nav-forward-block > 75 19% - python-syntax-context-type > 75 19% - syntax-ppss > 74 19% parse-partial-sexp > 1 0% - python-nav-beginning-of-statement > 1 0% point-marker > 1 0% current-indentation > 170 44% - let > 170 44% - if > 170 44% - funcall > 170 44% - thing-at-point--beginning-of-sexp > 170 44% - let > 170 44% - if > 170 44% - forward-sexp > 170 44% - python-nav-forward-sexp > 170 44% - python-nav--forward-sexp > 170 44% - python-info-statement-ends-block-p > 170 44% - python-nav-end-of-block > 95 24% - python-nav-end-of-statement > 63 16% - syntax-ppss > 62 16% parse-partial-sexp > 31 8% - python-info-line-ends-backslash-p > 31 8% - syntax-ppss > 30 7% parse-partial-sexp > 1 0% re-search-forward > 75 19% - python-nav-beginning-of-block > 75 19% - python-nav-backward-block > 75 19% - python-nav-forward-block > 72 18% - python-syntax-context-type > 72 18% - syntax-ppss > 71 18% parse-partial-sexp > 2 0% re-search-backward > 1 0% - python-nav-beginning-of-statement > 1 0% - python-info-line-ends-backslash-p > 1 0% - syntax-ppss > 1 0% syntax-ppss--data > 2 0% - python-shell-get-process > 2 0% - python-shell-get-buffer > 2 0% - seq-some > 2 0% + seq-do > 32 8% Automatic GC > 6 1% - command-execute > 6 1% - call-interactively > 6 1% - byte-code > 6 1% - read-extended-command > 6 1% - read-extended-command-1 > 6 1% - completing-read > 6 1% - completing-read-default > 6 1% - read-from-minibuffer > 1 0% redisplay_internal (C function) > 2 0% redisplay_internal (C function) Please give me some time as I'm trying to improve performance.
bug-gnu-emacs <at> gnu.org:bug#77620; Package emacs.
(Wed, 09 Apr 2025 15:53:02 GMT) Full text and rfc822 format available.Message #14 received at 77620 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: kobarity <kobarity <at> gmail.com> Cc: 77620 <at> debbugs.gnu.org, jdtsmith <at> gmail.com Subject: Re: bug#77620: thingatpt can be incredibly slow in python-mode buffers Date: Wed, 09 Apr 2025 18:52:18 +0300
> Date: Thu, 10 Apr 2025 00:33:03 +0900 > From: kobarity <kobarity <at> gmail.com> > Cc: JD Smith <jdtsmith <at> gmail.com>, > 77620 <at> debbugs.gnu.org > > Eli Zaretskii wrote: > > > > > In #77588 this was shown to lead to long intermittent pauses with eglot in large python buffers, but the issue is more general for any packages using thingatpt in python buffers. > > > > The Lisp profile, which seems to point to the likely culprit, is > > below. > > > > Maybe kobarity (CC'ed) will have some ideas or suggestions. > > > > 345 89% - ... > > 343 89% - cond > > 343 89% - let > > 343 89% - condition-case > > 343 89% - progn > > 343 89% - save-excursion > > 173 44% - funcall > > 173 44% - thing-at-point--end-of-sexp > > 173 44% - let > > 173 44% - if > > 173 44% - condition-case > > 173 44% - forward-sexp > > 173 44% - python-nav-forward-sexp > > 173 44% - python-nav--forward-sexp > > 173 44% - python-info-statement-ends-block-p > > 173 44% - python-nav-end-of-block > > 96 24% - python-nav-end-of-statement > > 69 17% - syntax-ppss > > 67 17% parse-partial-sexp > > 27 7% - python-info-line-ends-backslash-p > > 27 7% - syntax-ppss > > 27 7% parse-partial-sexp > > 76 19% - python-nav-beginning-of-block > > 76 19% - python-nav-backward-block > > 76 19% - python-nav-forward-block > > 75 19% - python-syntax-context-type > > 75 19% - syntax-ppss > > 74 19% parse-partial-sexp > > 1 0% - python-nav-beginning-of-statement > > 1 0% point-marker > > 1 0% current-indentation > > 170 44% - let > > 170 44% - if > > 170 44% - funcall > > 170 44% - thing-at-point--beginning-of-sexp > > 170 44% - let > > 170 44% - if > > 170 44% - forward-sexp > > 170 44% - python-nav-forward-sexp > > 170 44% - python-nav--forward-sexp > > 170 44% - python-info-statement-ends-block-p > > 170 44% - python-nav-end-of-block > > 95 24% - python-nav-end-of-statement > > 63 16% - syntax-ppss > > 62 16% parse-partial-sexp > > 31 8% - python-info-line-ends-backslash-p > > 31 8% - syntax-ppss > > 30 7% parse-partial-sexp > > 1 0% re-search-forward > > 75 19% - python-nav-beginning-of-block > > 75 19% - python-nav-backward-block > > 75 19% - python-nav-forward-block > > 72 18% - python-syntax-context-type > > 72 18% - syntax-ppss > > 71 18% parse-partial-sexp > > 2 0% re-search-backward > > 1 0% - python-nav-beginning-of-statement > > 1 0% - python-info-line-ends-backslash-p > > 1 0% - syntax-ppss > > 1 0% syntax-ppss--data > > 2 0% - python-shell-get-process > > 2 0% - python-shell-get-buffer > > 2 0% - seq-some > > 2 0% + seq-do > > 32 8% Automatic GC > > 6 1% - command-execute > > 6 1% - call-interactively > > 6 1% - byte-code > > 6 1% - read-extended-command > > 6 1% - read-extended-command-1 > > 6 1% - completing-read > > 6 1% - completing-read-default > > 6 1% - read-from-minibuffer > > 1 0% redisplay_internal (C function) > > 2 0% redisplay_internal (C function) > > Please give me some time as I'm trying to improve performance. Sure, there's no rush. TIA.
bug-gnu-emacs <at> gnu.org:bug#77620; Package emacs.
(Sun, 20 Apr 2025 15:06:01 GMT) Full text and rfc822 format available.Message #17 received at 77620 <at> debbugs.gnu.org (full text, mbox):
From: kobarity <kobarity <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org>, jdtsmith <at> gmail.com Cc: 77620 <at> debbugs.gnu.org Subject: Re: bug#77620: thingatpt can be incredibly slow in python-mode buffers Date: Mon, 21 Apr 2025 00:05:37 +0900
[Message part 1 (text/plain, inline)]
Eli Zaretskii wrote:
>
> > Date: Thu, 10 Apr 2025 00:33:03 +0900
> > From: kobarity <kobarity <at> gmail.com>
> > Cc: JD Smith <jdtsmith <at> gmail.com>,
> > 77620 <at> debbugs.gnu.org
> >
> > Eli Zaretskii wrote:
> > >
> > > > In #77588 this was shown to lead to long intermittent pauses with eglot in large python buffers, but the issue is more general for any packages using thingatpt in python buffers.
> > >
> > > The Lisp profile, which seems to point to the likely culprit, is
> > > below.
> > >
> > > Maybe kobarity (CC'ed) will have some ideas or suggestions.
> > >
> > > 345 89% - ...
> > > 343 89% - cond
> > > 343 89% - let
> > > 343 89% - condition-case
> > > 343 89% - progn
> > > 343 89% - save-excursion
> > > 173 44% - funcall
> > > 173 44% - thing-at-point--end-of-sexp
> > > 173 44% - let
> > > 173 44% - if
> > > 173 44% - condition-case
> > > 173 44% - forward-sexp
> > > 173 44% - python-nav-forward-sexp
> > > 173 44% - python-nav--forward-sexp
> > > 173 44% - python-info-statement-ends-block-p
> > > 173 44% - python-nav-end-of-block
> > > 96 24% - python-nav-end-of-statement
> > > 69 17% - syntax-ppss
> > > 67 17% parse-partial-sexp
> > > 27 7% - python-info-line-ends-backslash-p
> > > 27 7% - syntax-ppss
> > > 27 7% parse-partial-sexp
> > > 76 19% - python-nav-beginning-of-block
> > > 76 19% - python-nav-backward-block
> > > 76 19% - python-nav-forward-block
> > > 75 19% - python-syntax-context-type
> > > 75 19% - syntax-ppss
> > > 74 19% parse-partial-sexp
> > > 1 0% - python-nav-beginning-of-statement
> > > 1 0% point-marker
> > > 1 0% current-indentation
> > > 170 44% - let
> > > 170 44% - if
> > > 170 44% - funcall
> > > 170 44% - thing-at-point--beginning-of-sexp
> > > 170 44% - let
> > > 170 44% - if
> > > 170 44% - forward-sexp
> > > 170 44% - python-nav-forward-sexp
> > > 170 44% - python-nav--forward-sexp
> > > 170 44% - python-info-statement-ends-block-p
> > > 170 44% - python-nav-end-of-block
> > > 95 24% - python-nav-end-of-statement
> > > 63 16% - syntax-ppss
> > > 62 16% parse-partial-sexp
> > > 31 8% - python-info-line-ends-backslash-p
> > > 31 8% - syntax-ppss
> > > 30 7% parse-partial-sexp
> > > 1 0% re-search-forward
> > > 75 19% - python-nav-beginning-of-block
> > > 75 19% - python-nav-backward-block
> > > 75 19% - python-nav-forward-block
> > > 72 18% - python-syntax-context-type
> > > 72 18% - syntax-ppss
> > > 71 18% parse-partial-sexp
> > > 2 0% re-search-backward
> > > 1 0% - python-nav-beginning-of-statement
> > > 1 0% - python-info-line-ends-backslash-p
> > > 1 0% - syntax-ppss
> > > 1 0% syntax-ppss--data
> > > 2 0% - python-shell-get-process
> > > 2 0% - python-shell-get-buffer
> > > 2 0% - seq-some
> > > 2 0% + seq-do
> > > 32 8% Automatic GC
> > > 6 1% - command-execute
> > > 6 1% - call-interactively
> > > 6 1% - byte-code
> > > 6 1% - read-extended-command
> > > 6 1% - read-extended-command-1
> > > 6 1% - completing-read
> > > 6 1% - completing-read-default
> > > 6 1% - read-from-minibuffer
> > > 1 0% redisplay_internal (C function)
> > > 2 0% redisplay_internal (C function)
> >
> > Please give me some time as I'm trying to improve performance.
>
> Sure, there's no rush. TIA.
In the process of looking into #77620, I noticed bugs in the
end-of-block detection functions. So I submitted a patch to #77941.
Please note that the patch attached to this mail assumes the #77941
patch.
In my environment, the next test shows about 2 seconds on _axes.py's
L8817.
> (/ (car (benchmark-run 10 (thing-at-point 'sexp))) 10)
But there are worse cases. Let's add the next two lines to the end of
_axes.py with 4-character indent.
a = 1
b = 2
The same measurement at the end of line "a = 1" gives 6 seconds; at
the end of line "b = 2" it gives 7 seconds. This is because it calls
time-consuming functions many times.
`python-nav-beginning-of-block' and `python-nav-end-of-block' are very
time consuming if the block is large. In the case of _axes.py, "class
Axes" is a large block with over 8000 lines.
However, `python-nav-forward-sexp' that (thing-at-point 'sexp) calls
does not necessarily have to perform these functions. They are just
called by `python-info-statement-ends-block-p': (Before #77941 patch)
(defun python-info-statement-ends-block-p ()
"Return non-nil if point is at end of block."
(let ((end-of-block-pos (save-excursion
(python-nav-end-of-block)))
(end-of-statement-pos (save-excursion
(python-nav-end-of-statement))))
(and end-of-block-pos end-of-statement-pos
(= end-of-block-pos end-of-statement-pos))))
The logic is that if the end of the current statement is the end of
the current block, then it is the last line of the block. This is not
wrong, but the problem is that it takes time to move to the end of the
block.
Fortunately, in many cases it is much easier to determine that it is
not the end of the block. Specifically, if the indentation of the
next statement is equal to or greater than the indentation of the
current statement, then the current statement cannot be the end of the
block. The attached patch
0001-Performance-optimization-of-python-info-statement-en.patch takes
advantage of this to improve the performance of
`python-info-statement-ends-block-p'. Please remember that it assumes
the #77941 patch is applied.
0001-Performance-optimization-of-python-info-statement-en.patch solves
the performance problem with _axes.py, but does not have much effect
on the problem with lines "a = 1" and "b = 2" added above. The
attached patch
0002-Add-cache-to-Python-block-navigation-functions.patch is an
attempt to introduce a cache to alleviate this problem.
I measured the following to disable the cache for each benchmark.
(/ (car (benchmark-run 10 (progn (thing-at-point 'sexp) (setq python-nav-cache nil)))) 10)
It shows about 1.6 seconds for both "a = 1" and "b = 2" lines.
I believe 0002-Add-cache-to-Python-block-navigation-functions.patch is
a PoC level patch, so I welcome opinions on what you think of this
direction.
[0001-Performance-optimization-of-python-info-statement-en.patch (application/octet-stream, attachment)]
[0002-Add-cache-to-Python-block-navigation-functions.patch (application/octet-stream, attachment)]
bug-gnu-emacs <at> gnu.org:bug#77620; Package emacs.
(Mon, 21 Apr 2025 14:23:02 GMT) Full text and rfc822 format available.Message #20 received at 77620 <at> debbugs.gnu.org (full text, mbox):
From: kobarity <kobarity <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org>, jdtsmith <at> gmail.com Cc: 77620 <at> debbugs.gnu.org Subject: Re: bug#77620: thingatpt can be incredibly slow in python-mode buffers Date: Mon, 21 Apr 2025 23:22:14 +0900
[Message part 1 (text/plain, inline)]
kobarity wrote: > In the process of looking into #77620, I noticed bugs in the > end-of-block detection functions. So I submitted a patch to #77941. > Please note that the patch attached to this mail assumes the #77941 > patch. > > In my environment, the next test shows about 2 seconds on _axes.py's > L8817. > > > (/ (car (benchmark-run 10 (thing-at-point 'sexp))) 10) > > But there are worse cases. Let's add the next two lines to the end of > _axes.py with 4-character indent. > > a = 1 > b = 2 > > The same measurement at the end of line "a = 1" gives 6 seconds; at > the end of line "b = 2" it gives 7 seconds. This is because it calls > time-consuming functions many times. > > `python-nav-beginning-of-block' and `python-nav-end-of-block' are very > time consuming if the block is large. In the case of _axes.py, "class > Axes" is a large block with over 8000 lines. > > However, `python-nav-forward-sexp' that (thing-at-point 'sexp) calls > does not necessarily have to perform these functions. They are just > called by `python-info-statement-ends-block-p': (Before #77941 patch) > > (defun python-info-statement-ends-block-p () > "Return non-nil if point is at end of block." > (let ((end-of-block-pos (save-excursion > (python-nav-end-of-block))) > (end-of-statement-pos (save-excursion > (python-nav-end-of-statement)))) > (and end-of-block-pos end-of-statement-pos > (= end-of-block-pos end-of-statement-pos)))) > > The logic is that if the end of the current statement is the end of > the current block, then it is the last line of the block. This is not > wrong, but the problem is that it takes time to move to the end of the > block. > > Fortunately, in many cases it is much easier to determine that it is > not the end of the block. Specifically, if the indentation of the > next statement is equal to or greater than the indentation of the > current statement, then the current statement cannot be the end of the > block. The attached patch > 0001-Performance-optimization-of-python-info-statement-en.patch takes > advantage of this to improve the performance of > `python-info-statement-ends-block-p'. Please remember that it assumes > the #77941 patch is applied. > > 0001-Performance-optimization-of-python-info-statement-en.patch solves > the performance problem with _axes.py, but does not have much effect > on the problem with lines "a = 1" and "b = 2" added above. The > attached patch > 0002-Add-cache-to-Python-block-navigation-functions.patch is an > attempt to introduce a cache to alleviate this problem. > > I measured the following to disable the cache for each benchmark. > > (/ (car (benchmark-run 10 (progn (thing-at-point 'sexp) (setq python-nav-cache nil)))) 10) > > It shows about 1.6 seconds for both "a = 1" and "b = 2" lines. > > I believe 0002-Add-cache-to-Python-block-navigation-functions.patch is > a PoC level patch, so I welcome opinions on what you think of this > direction. I revised 0002-Add-cache-to-Python-block-navigation-functions.patch. There was no need to use a macro.
[0002-Add-cache-to-Python-block-navigation-functions.patch (application/octet-stream, attachment)]
Eli Zaretskii <eliz <at> gnu.org>:JD Smith <jdtsmith <at> gmail.com>:Message #25 received at 77620-done <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: kobarity <kobarity <at> gmail.com> Cc: 77620-done <at> debbugs.gnu.org, jdtsmith <at> gmail.com Subject: Re: bug#77620: thingatpt can be incredibly slow in python-mode buffers Date: Sat, 26 Apr 2025 14:22:59 +0300
> Date: Mon, 21 Apr 2025 23:22:14 +0900 > From: kobarity <kobarity <at> gmail.com> > Cc: 77620 <at> debbugs.gnu.org > > kobarity wrote: > > In the process of looking into #77620, I noticed bugs in the > > end-of-block detection functions. So I submitted a patch to #77941. > > Please note that the patch attached to this mail assumes the #77941 > > patch. > > > > In my environment, the next test shows about 2 seconds on _axes.py's > > L8817. > > > > > (/ (car (benchmark-run 10 (thing-at-point 'sexp))) 10) > > > > But there are worse cases. Let's add the next two lines to the end of > > _axes.py with 4-character indent. > > > > a = 1 > > b = 2 > > > > The same measurement at the end of line "a = 1" gives 6 seconds; at > > the end of line "b = 2" it gives 7 seconds. This is because it calls > > time-consuming functions many times. > > > > `python-nav-beginning-of-block' and `python-nav-end-of-block' are very > > time consuming if the block is large. In the case of _axes.py, "class > > Axes" is a large block with over 8000 lines. > > > > However, `python-nav-forward-sexp' that (thing-at-point 'sexp) calls > > does not necessarily have to perform these functions. They are just > > called by `python-info-statement-ends-block-p': (Before #77941 patch) > > > > (defun python-info-statement-ends-block-p () > > "Return non-nil if point is at end of block." > > (let ((end-of-block-pos (save-excursion > > (python-nav-end-of-block))) > > (end-of-statement-pos (save-excursion > > (python-nav-end-of-statement)))) > > (and end-of-block-pos end-of-statement-pos > > (= end-of-block-pos end-of-statement-pos)))) > > > > The logic is that if the end of the current statement is the end of > > the current block, then it is the last line of the block. This is not > > wrong, but the problem is that it takes time to move to the end of the > > block. > > > > Fortunately, in many cases it is much easier to determine that it is > > not the end of the block. Specifically, if the indentation of the > > next statement is equal to or greater than the indentation of the > > current statement, then the current statement cannot be the end of the > > block. The attached patch > > 0001-Performance-optimization-of-python-info-statement-en.patch takes > > advantage of this to improve the performance of > > `python-info-statement-ends-block-p'. Please remember that it assumes > > the #77941 patch is applied. > > > > 0001-Performance-optimization-of-python-info-statement-en.patch solves > > the performance problem with _axes.py, but does not have much effect > > on the problem with lines "a = 1" and "b = 2" added above. The > > attached patch > > 0002-Add-cache-to-Python-block-navigation-functions.patch is an > > attempt to introduce a cache to alleviate this problem. > > > > I measured the following to disable the cache for each benchmark. > > > > (/ (car (benchmark-run 10 (progn (thing-at-point 'sexp) (setq python-nav-cache nil)))) 10) > > > > It shows about 1.6 seconds for both "a = 1" and "b = 2" lines. > > > > I believe 0002-Add-cache-to-Python-block-navigation-functions.patch is > > a PoC level patch, so I welcome opinions on what you think of this > > direction. > > I revised 0002-Add-cache-to-Python-block-navigation-functions.patch. > There was no need to use a macro. Thanks, installed, and closing the bug.
Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org.
(Sun, 25 May 2025 11:24:12 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.