[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#44610: 27.1; Keyboard Macro Performance Problem
From: |
Robert Thorpe |
Subject: |
bug#44610: 27.1; Keyboard Macro Performance Problem |
Date: |
Sun, 15 Nov 2020 23:44:32 +0000 |
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Robert Thorpe <rt@robertthorpeconsulting.com>
>> Date: Fri, 13 Nov 2020 02:51:12 +0000
>>
>>
>> This bug report comes from a discussion on Emacs reddit.
>>
>> Start with a blank buffer and create about ~300 lines of the string:
>>
>> ffffffffffffffffffff (pppppppppppppppppppp);
>>
>> This will be turned into:
>>
>> 'ffffffffffffffffffff':
>>
>> That can be done using the following keyboard macro: M-m ' M-f ' : C-k
>> C-n
>>
>> You can apply that to every line in the buffer using C-u 300 f4.
>>
>> Now here's the strange bit. In a fundamental-mode buffer this is
>> extremely fast, nearly instantaneous. But, in a python-mode buffer it
>> takes 20 to 30 seconds. If the mode is c-mode then it is also much
>> slower than fundamental-mode. It will also exceed the variable binding
>> depth in some cases. Oddly it is faster if you use forward-line instead
>> of C-n.
>
> I suggest to produce and present a profile of this. Invoke this macro
> after "M-x profiler-start RET RET", then "M-x profiler-report RET",
> expand the profile fully by "C-u RET" on the top line, and post the
> result here. That should give some clues.
Here is the report. I did it in Python-mode using Emacs -Q on Emacs
27.1. My machine is a Dell 14-3480. The profile I've got seems to be a
bit different to the one Jean Louis got.
It is a little faster using Emacs -Q than my own init, but it's
still fairly slow.
I notice that in my report the GC is taking about 39% of runtime. I'm
not sure why it's taking longer than in Jen Louis' report.
It's faster if I use forward-line rather than pressing C-n. Also the
report looks very different. I've added that at the end. The first
report is the one using C-n.
- command-execute 3499 60%
- call-interactively 3499 60%
- funcall-interactively 3480 59%
- kmacro-end-or-call-macro 3474 59%
- kmacro-call-macro 3474 59%
- call-last-kbd-macro 3464 59%
- command-execute 3419 58%
- call-interactively 3417 58%
- funcall-interactively 3417 58%
- next-line 3345 57%
- line-move 3345 57%
- line-move-visual 3339 57%
- vertical-motion 3132 53%
- jit-lock-function 3132 53%
- jit-lock-fontify-now 3131 53%
- jit-lock--run-functions 3112 53%
- run-hook-wrapped 3112 53%
- #<compiled 0x15629e8957cd> 3111 53%
- font-lock-fontify-region 3111 53%
- font-lock-default-fontify-region 3111 53%
- font-lock-fontify-syntactically-region 3082
53%
- python-font-lock-syntactic-face-function
3063 52%
- python-info-docstring-p 3055 52%
- python-nav-backward-sexp 3016 51%
- python-nav-forward-sexp 3007 51%
- python-nav--forward-sexp 2968 51%
- python-info-beginning-of-block-p 2005
34%
- python-info-beginning-of-statement-p
1670 28%
- python-nav-beginning-of-statement
1644 28%
- syntax-ppss 1392 23%
#<compiled 0x15629eb1977d> 1
0%
- python-info-line-ends-backslash-p
138 2%
- syntax-ppss 103 1%
#<compiled 0x15629ea9bac1> 1
0%
back-to-indentation 56 0%
- python-info-statement-starts-block-p
314 5%
- python-nav-beginning-of-statement
277 4%
- python-info-line-ends-backslash-p
112 1%
syntax-ppss 76 1%
- syntax-ppss 82 1%
#<compiled 0x15629ea55d29> 3
0%
back-to-indentation 33 0%
- python-info-end-of-block-p 385 6%
- python-info-end-of-statement-p 370
6%
- python-nav-end-of-statement 359
6%
- syntax-ppss 185 3%
#<compiled 0x15629eb2ece5> 2
0%
- python-info-line-ends-backslash-p
104 1%
- syntax-ppss 87 1%
#<compiled 0x15629ea943f5> 2
0%
- python-info-beginning-of-statement-p
274 4%
- python-nav-beginning-of-statement
252 4%
- python-info-line-ends-backslash-p
105 1%
- syntax-ppss 76 1%
#<compiled 0x15629eb1e6a1> 1
0%
syntax-ppss 72 1%
back-to-indentation 44 0%
- python-nav-beginning-of-statement
107 1%
- syntax-ppss 37 0%
#<compiled 0x15629eb2a9b5> 1 0%
- python-info-line-ends-backslash-p
29 0%
syntax-ppss 20 0%
back-to-indentation 21 0%
- python-nav--lisp-forward-sexp 63
1%
forward-sexp 58 0%
- python-info-current-line-empty-p 45
0%
match-string-no-properties 6 0%
- python-syntax-context-type 39 0%
syntax-ppss 28 0%
- python-info-statement-ends-block-p
2 0%
- python-nav-end-of-block 1 0%
- python-nav-beginning-of-block 1
0%
python-info-current-line-empty-p
1 0%
- python-nav-end-of-statement 1 0%
syntax-ppss 1 0%
syntax-after 2 0%
syntax-class 1 0%
- python-nav-beginning-of-statement 2
0%
syntax-ppss 2 0%
- python-info-assignment-statement-p 1
0%
- python-nav-beginning-of-statement 1
0%
python-info-line-ends-backslash-p 1
0%
syntax-ppss 18 0%
- font-lock-fontify-keywords-region 27 0%
#<compiled 0x15629e89743d> 11 0%
#<compiled 0x15629e897459> 7 0%
- run-with-timer 16 0%
- apply 16 0%
- run-at-time 15 0%
- timer-activate 13 0%
- timer--activate 12 0%
timer--time-less-p 12 0%
timer-relative-time 1 0%
- posn-at-point 50 0%
- jit-lock-function 40 0%
- jit-lock-fontify-now 39 0%
- jit-lock--run-functions 38 0%
- run-hook-wrapped 38 0%
- #<compiled 0x15629eb1cfd5> 38 0%
- font-lock-fontify-region 38 0%
- font-lock-default-fontify-region 36 0%
- font-lock-fontify-syntactically-region 33
0%
- python-font-lock-syntactic-face-function
33 0%
- python-info-docstring-p 32 0%
- python-nav-backward-sexp 26 0%
- python-nav-forward-sexp 26 0%
- python-nav--forward-sexp 25 0%
- python-syntax-context-type 7 0%
syntax-ppss 7 0%
- python-info-beginning-of-block-p 6
0%
python-info-statement-starts-block-p
4 0%
python-info-beginning-of-statement-p
1 0%
- python-nav-beginning-of-statement
4 0%
syntax-ppss 3 0%
python-info-line-ends-backslash-p
1 0%
- python-info-beginning-of-statement-p
2 0%
python-nav-beginning-of-statement
1 0%
- python-nav--lisp-forward-sexp 2
0%
forward-sexp 2 0%
- python-info-end-of-block-p 1 0%
python-info-end-of-statement-p 1
0%
python-info-current-line-empty-p 1
0%
python-nav-beginning-of-statement 2
0%
- python-info-assignment-statement-p 1
0%
- python-nav-beginning-of-statement 1
0%
- python-info-line-ends-backslash-p 1
0%
syntax-ppss 1 0%
- font-lock-fontify-keywords-region 3 0%
#<compiled 0x15629e89743d> 2 0%
- eval 6 0%
if 2 0%
mode-line-eol-desc 2 0%
file-remote-p 4 0%
- window-inside-pixel-edges 1 0%
window-edges 1 0%
- self-insert-command 51 0%
- python-indent-post-self-insert-function 48 0%
- syntax-ppss 48 0%
- syntax-propertize 6 0%
#<compiled 0x15629e89748d> 3 0%
syntax-ppss-flush-cache 1 0%
electric-indent-post-self-insert-function 1 0%
- jit-lock-after-change 1 0%
run-hook-with-args 1 0%
- kill-line 14 0%
- kill-region 14 0%
- kill-new 14 0%
- gui-select-text 12 0%
- gui-set-selection 12 0%
- gui-backend-set-selection 12 0%
- apply 11 0%
#<compiled 0x1fd8bb00bf7f> 11 0%
menu-bar-update-yank-menu 1 0%
- jit-lock--antiblink-post-command 35 0%
- syntax-ppss 29 0%
- syntax-propertize 5 0%
#<compiled 0x15629e89748d> 1 0%
- run-with-idle-timer 2 0%
- timer-set-idle-time 2 0%
timer--time-setter 2 0%
cancel-timer 1 0%
- undo-auto--add-boundary 3 0%
undo-auto--boundaries 1 0%
- execute-extended-command 6 0%
- sit-for 5 0%
redisplay 3 0%
- command-execute 1 0%
- call-interactively 1 0%
- funcall-interactively 1 0%
profiler-report 1 0%
- byte-code 19 0%
- read-extended-command 19 0%
- completing-read 19 0%
- completing-read-default 19 0%
- read-from-minibuffer 10 0%
- redisplay_internal (C function) 1 0%
- tool-bar-make-keymap 1 0%
- tool-bar-make-keymap-1 1 0%
- mapcar 1 0%
- #<compiled 0x1fd8bb03930b> 1 0%
- eval 1 0%
- find-image 1 0%
image-search-load-path 1 0%
+ ... 2303 39%
+ redisplay_internal (C function) 1 0%
The following report is from using M-x forward-line instead of C-n:
- redisplay_internal (C function) 1237 38%
- jit-lock-function 1212 37%
- jit-lock-fontify-now 1212 37%
- jit-lock--run-functions 1212 37%
- run-hook-wrapped 1212 37%
- #<compiled 0x15629ead2fe5> 1212 37%
- font-lock-fontify-region 1212 37%
- font-lock-default-fontify-region 1212 37%
- font-lock-fontify-syntactically-region 1196 37%
- python-font-lock-syntactic-face-function 1191 37%
- python-info-docstring-p 1189 36%
- python-nav-backward-sexp 1172 36%
- python-nav-forward-sexp 1168 36%
- python-nav--forward-sexp 1154 35%
- python-info-beginning-of-block-p 767 23%
- python-info-beginning-of-statement-p 666 20%
- python-nav-beginning-of-statement 656 20%
syntax-ppss 589 18%
- python-info-line-ends-backslash-p 44 1%
syntax-ppss 30 0%
back-to-indentation 11 0%
- python-info-statement-starts-block-p 97 3%
- python-nav-beginning-of-statement 84 2%
- python-info-line-ends-backslash-p 34 1%
syntax-ppss 22 0%
syntax-ppss 25 0%
back-to-indentation 11 0%
- python-info-end-of-block-p 162 5%
- python-info-end-of-statement-p 158 4%
- python-nav-end-of-statement 154 4%
syntax-ppss 80 2%
- python-info-line-ends-backslash-p 53 1%
syntax-ppss 46 1%
- python-info-beginning-of-statement-p 108 3%
- python-nav-beginning-of-statement 101 3%
- python-info-line-ends-backslash-p 43 1%
syntax-ppss 34 1%
syntax-ppss 27 0%
back-to-indentation 17 0%
- python-nav-beginning-of-statement 47 1%
- python-info-line-ends-backslash-p 20 0%
syntax-ppss 13 0%
syntax-ppss 17 0%
back-to-indentation 4 0%
- python-syntax-context-type 20 0%
syntax-ppss 18 0%
- python-nav--lisp-forward-sexp 16 0%
forward-sexp 15 0%
- python-info-current-line-empty-p 15 0%
match-string-no-properties 2 0%
- python-info-statement-ends-block-p 1 0%
python-nav-end-of-statement 1 0%
syntax-class 1 0%
syntax-after 1 0%
- python-nav-beginning-of-statement 5 0%
syntax-ppss 3 0%
- python-info-line-ends-backslash-p 2 0%
syntax-ppss 2 0%
- python-info-assignment-statement-p 1 0%
- python-nav-beginning-of-statement 1 0%
syntax-ppss 1 0%
syntax-ppss 3 0%
- replace-regexp-in-string 1 0%
apply 1 0%
- font-lock-fontify-keywords-region 15 0%
#<compiled 0x15629e89743d> 9 0%
#<compiled 0x15629e897459> 5 0%
- eval 9 0%
if 7 0%
- unless 1 0%
- if 1 0%
- display-graphic-p 1 0%
framep-on-display 1 0%
- tool-bar-make-keymap 5 0%
- tool-bar-make-keymap-1 5 0%
- mapcar 5 0%
- #<compiled 0x1fd8bb03930b> 5 0%
- eval 4 0%
- find-image 4 0%
image-search-load-path 3 0%
- #<compiled 0x1fd8bb05b46f> 3 0%
- apply 3 0%
- redisplay--pre-redisplay-functions 3 0%
- run-hook-with-args 2 0%
- redisplay--update-region-highlight 1 0%
#<compiled 0x1fd8baff3977> 1 0%
- mode-line-default-help-echo 3 0%
- window-at-side-p 2 0%
- window-pixel-edges 2 0%
window-edges 1 0%
file-remote-p 3 0%
x-gtk-map-stock 1 0%
- command-execute 988 30%
- call-interactively 986 30%
- funcall-interactively 889 27%
- kmacro-end-or-call-macro 617 19%
- kmacro-call-macro 617 19%
- call-last-kbd-macro 592 18%
- command-execute 540 16%
- call-interactively 531 16%
- byte-code 412 12%
- read-extended-command 412 12%
- completing-read 410 12%
- completing-read-default 409 12%
- read-from-minibuffer 48 1%
- command-execute 23 0%
- call-interactively 15 0%
- funcall-interactively 15 0%
- self-insert-command 7 0%
#<compiled 0x1fd8baffa1bd> 3 0%
- minibuffer-complete-and-exit 4 0%
- completion-complete-and-exit 4 0%
- completion--complete-and-exit 2 0%
- test-completion 2 0%
- #<compiled 0x1fd8baff9e61> 2 0%
- complete-with-action 2 0%
test-completion 2 0%
- minibuffer-inactive-mode 11 0%
- run-mode-hooks 7 0%
- run-hooks 7 0%
- global-font-lock-mode-enable-in-buffers 7
0%
- turn-on-font-lock-if-desired 7 0%
- turn-on-font-lock 7 0%
- font-lock-mode 7 0%
font-lock-default-function 3 0%
called-interactively-p 2 0%
- kill-all-local-variables 2 0%
global-eldoc-mode-cmhh 1 0%
- window--sanitize-window-sizes 3 0%
- walk-window-tree 2 0%
- walk-window-tree-1 2 0%
- #<compiled 0x15629e90c20d> 2 0%
- window-min-size 2 0%
- window--min-size-1 1 0%
window-size-fixed-p 1 0%
- frame-windows-min-size 2 0%
- window-min-size 2 0%
- window--min-size-1 1 0%
- window-size-fixed-p 1 0%
window--size-fixed-1 1 0%
clear-minibuffer-message 1 0%
#<compiled 0x15629ea97fd1> 1 0%
add-hook 1 0%
- funcall-interactively 116 3%
- self-insert-command 47 1%
- python-indent-post-self-insert-function 39 1%
- syntax-ppss 39 1%
- syntax-propertize 4 0%
#<compiled 0x15629e89748d> 2 0%
- electric-indent-post-self-insert-function 4 0%
- syntax-ppss 4 0%
syntax-propertize 1 0%
- jit-lock-after-change 2 0%
run-hook-with-args 1 0%
- execute-extended-command 42 1%
- sit-for 41 1%
- redisplay 2 0%
- redisplay_internal (C function) 2 0%
- jit-lock-function 2 0%
- jit-lock-fontify-now 2 0%
- jit-lock--run-functions 2 0%
- run-hook-wrapped 2 0%
- #<compiled 0x15629e917a4d> 2 0%
- font-lock-fontify-region 2 0%
- font-lock-default-fontify-region 2 0%
- font-lock-fontify-keywords-region 2 0%
#<compiled 0x15629e89743d> 2 0%
input-pending-p 2 0%
- kill-line 20 0%
- kill-region 18 0%
- kill-new 13 0%
- gui-select-text 10 0%
- gui-set-selection 10 0%
- gui-backend-set-selection 10 0%
- apply 10 0%
#<compiled 0x1fd8bb00bf7f> 10 0%
menu-bar-update-yank-menu 2 0%
- filter-buffer-substring 3 0%
- buffer-substring--filter 3 0%
- #<compiled 0x15629ea7fcf5> 3 0%
- apply 3 0%
- #<compiled 0x1fd8bafd224d> 3 0%
delete-and-extract-region 1 0%
back-to-indentation 1 0%
- jit-lock--antiblink-post-command 42 1%
syntax-ppss 36 1%
- run-with-idle-timer 1 0%
- timer-activate-when-idle 1 0%
- timer--activate 1 0%
timer--time-less-p 1 0%
global-font-lock-mode-check-buffers 2 0%
undo-auto--add-boundary 1 0%
- execute-extended-command 224 6%
- execute-extended-command--shorter 194 6%
- completion-try-completion 194 6%
- completion--nth-completion 194 6%
- completion--some 194 6%
- #<compiled 0x15629eb8865d> 194 6%
- completion-pcm-try-completion 127 3%
- completion-pcm--find-all-completions 124 3%
completion-pcm--all-completions 123 3%
- completion-pcm--merge-try 2 0%
completion-pcm--merge-completions 1 0%
completion-basic-try-completion 67 2%
- sit-for 17 0%
redisplay 14 0%
- command-execute 10 0%
- call-interactively 10 0%
- byte-code 5 0%
- completing-read 5 0%
- completing-read-default 5 0%
read-from-minibuffer 1 0%
- funcall-interactively 4 0%
- profiler-report 3 0%
- profiler-report-cpu 3 0%
- profiler-report-profile-other-window 3 0%
- profiler-report-setup-buffer 2 0%
- profiler-report-render-calltree 2 0%
- profiler-report-rerender-calltree 2 0%
- profiler-report-render-calltree-1 2 0%
- profiler-calltree-build 2 0%
- profiler-calltree-build-unified 2 0%
- maphash 2 0%
#<compiled 0x15629e778d71> 1 0%
- switch-to-buffer-other-window 1 0%
- pop-to-buffer 1 0%
- display-buffer 1 0%
- display-buffer--maybe-pop-up-frame-or-window 1
0%
- display-buffer--maybe-pop-up-window 1 0%
- display-buffer-pop-up-window 1 0%
window--maybe-raise-frame 1 0%
- python-mode 1 0%
python-indent-guess-indent-offset 1 0%
#<compiled 0x15629eacb3e5> 1 0%
- yank 26 0%
- push-mark 17 0%
mark 1 0%
insert-for-yank 5 0%
- current-kill 3 0%
- gui-selection-value 3 0%
- gui--selection-value-internal 3 0%
gui-get-selection 3 0%
- previous-line 9 0%
- line-move 9 0%
line-move-visual 7 0%
- profiler-report-toggle-entry 5 0%
- profiler-report-expand-entry 5 0%
- profiler-report-expand-entry 5 0%
- profiler-report-insert-calltree-children 5 0%
- mapc 5 0%
- profiler-report-insert-calltree 1 0%
- profiler-report-line-format 1 0%
- profiler-format 1 0%
- apply 1 0%
- profiler-format 1 0%
apply 1 0%
end-of-buffer 2 0%
- yank-pop 2 0%
insert-for-yank 1 0%
- kill-line 2 0%
- kill-region 2 0%
- kill-new 1 0%
- gui-select-text 1 0%
- gui-set-selection 1 0%
- gui-backend-set-selection 1 0%
- apply 1 0%
#<compiled 0x1fd8bb00bf7f> 1 0%
- filter-buffer-substring 1 0%
- buffer-substring--filter 1 0%
- #<compiled 0x15629e83a3c1> 1 0%
- apply 1 0%
- #<compiled 0x1fd8bafd224d> 1 0%
- delete-and-extract-region 1 0%
jit-lock-after-change 1 0%
- handle-focus-in 1 0%
- #<compiled 0x15629e827df9> 1 0%
- apply 1 0%
- blink-cursor--rescan-frames 1 0%
- blink-cursor-check 1 0%
- blink-cursor--start-idle-timer 1 0%
- run-with-idle-timer 1 0%
- timer-set-idle-time 1 0%
timer--time-setter 1 0%
- kmacro-start-macro-or-insert-counter 1 0%
kmacro-start-macro 1 0%
- byte-code 90 2%
- read-extended-command 80 2%
- completing-read 80 2%
- completing-read-default 80 2%
- read-from-minibuffer 46 1%
- undo-auto--add-boundary 2 0%
- undo-auto--boundaries 2 0%
undo-auto--ensure-boundary 2 0%
- redisplay_internal (C function) 2 0%
- tool-bar-make-keymap 1 0%
- tool-bar-make-keymap-1 1 0%
- mapcar 1 0%
- #<compiled 0x1fd8bb03930b> 1 0%
- eval 1 0%
- find-image 1 0%
- cond 1 0%
not 1 0%
- eval 1 0%
if 1 0%
- command-execute 1 0%
- call-interactively 1 0%
- funcall-interactively 1 0%
- self-insert-command 1 0%
electric-indent-post-self-insert-function 1 0%
- read-buffer-to-switch 10 0%
- read-buffer 10 0%
- completing-read-default 10 0%
- read-from-minibuffer 6 0%
- redisplay_internal (C function) 1 0%
x-gtk-map-stock 1 0%
- completing-read-default 7 0%
read-from-minibuffer 3 0%
+ ... 974 30%
+ timer-event-handler 6 0%
+ gui-set-selection 3 0%
+ deactivate-mark 2 0%
+ xselect-convert-to-string 1 0%
+ #<compiled 0x1fd8bb09a70d> 1 0%
clear-minibuffer-message 1 0%
+ undo-auto--add-boundary 1 0%
internal-timer-start-idle 1 0%
internal-echo-keystrokes-prefix 1 0%
BR,
Robert Thorpe