Skip Montanaro <skip(a)pobox.com> writes:
Adrian> Hi all, I wondered if someone else could try a M-x
flush-lines
Adrian> RET ^some-common-pattern RET on a file with a few thousand
Adrian> lines.
I'm not sure how you got that table, but my experience is that flush-lines
is a real dog (I'm using 21.5b16 at the moment). I occasionally have to
flush a few thousand lines matching "^ *#". These days I just get up and do
something else for a few minutes. It used to take a couple seconds with
21.4.x.
Hi Skip, All!
I identified the performance issue today.
It's present in both
(defun operate-on-non-matching-lines (regexp delete kill &optional beg end)
and
(defun operate-on-matching-lines (regexp delete kill &optional beg end)
due to the way they the count lines (a feature the GNU Emacs version
does not have) by first concating each match to a string.
This causes enormuous consing and the resulting GC activity makes
performance unbearable at the default gc-cons-threshold value.
Already using
(setq gc-cons-threshold 5000000)
I got 89s for my test case.
Function Name Ticks/Total %Usage Calls GC-Usage/ Total
=========================================/===== ====== ===== ========/=======
concat 55865/55871 62.448 2719 443787379/443787379
(in garbage collection) 31887/31902 35.644 87
delete-region 556/ 1083 0.622 2718 458724/ 687428
(profile overhead) 259/ 259 0.290
(in map-extents-internal) 234/ 255 0.262 24513 304796/ 304796
lazy-lock-after-change 118/ 250 0.132 2718 12/ 392
while 95/89313 0.106 1 448/444616854
re-search-forward 69/ 87 0.077 2719
(in char-byte conversion) 63/ 64 0.070 189410
if 42/ 1130 0.047 2723 280/ 687752
setq 29/56040 0.032 8154 0/443928698
(in redisplay) 28/ 38 0.031 23 448/ 448
get-text-property 25/ 32 0.028 2719
buffer-substring 21/ 49 0.023 2719 391456/ 467560
vertical-motion 21/ 43 0.023 5 64/ 64
save-excursion 19/89370 0.021 2719 0/444944595
lazy-lock-put-text-property 17/ 31 0.019 2718 0/ 380
and 17/ 116 0.019 2722 0/ 96
point-at-bol 16/ 29 0.018 2718
insert 14/ 14 0.016 1
forward-line 9/ 21 0.010 2718
window-end 9/ 21 0.010 4
(in internal-external conversion) 8/ 8 0.009 1267
beginning-of-line 8/ 17 0.009 2720
match-beginning 4/ 4 0.004 2718
progn 2/ 28 0.002 2718
next_event_internal() 2/ 2 0.002 23 112/ 112
count-lines 2/ 2 0.002 1
truncate-command-history-for-gc 2/ 2 0.002 87
not 2/ 2 0.002 2719
eobp 2/ 2 0.002 2719
goto-char 2/ 6 0.002 2718
make-saved-window 1/ 1 0.001 12 4032/ 5088
next-event 1/ 108 0.001 23 0/ 560
set-frame-pixel-size 1/ 1 0.001 1
mark-marker 1/ 1 0.001 17
event-buffer 1/ 1 0.001 8
point 1/ 1 0.001 5446
erase-buffer 1/ 1 0.001 8
lazy-lock-fontify-window 1/ 66 0.001 8
kill-buffer 1/ 1 0.001 1 24/ 96
reset-buffer 1/ 1 0.001 1 0/ 48
redisplay-echo-area 1/ 2 0.001 1
#<compiled-function nil "...(52)" [compilation-old-error-list
compilation-parsing-end compilation-mouse-motion-initiate-parsing e compilation-error-list
p nil t ((compile-reinitialize-errors nil p)) found (byte-code «¤Ä@@!© W«¥Aª±
X«§ÅÆÇ"¨ª¥ÅÆÈ"¨)ªYȧ [e p x l marker-position throw found t nil] 4) l] 2>
1/ 1 0.001 2
device-live-p 0/ 0 0.000 9
with-current-buffer 0/ 56 0.000 1 0/ 326249
mode-motion-highlight-internal 0/ 2 0.000 2 0/ 5328
dispatch-event 0/ 4 0.000 23 280/ 13280
itimer-restart 0/ 0 0.000 4
vector 0/ 0 0.000 19 1388/ 1388
window-dedicated-p 0/ 0 0.000 12
gethash 0/ 0 0.000 47
puthash 0/ 0 0.000 8
itimer-timer-driver 0/ 0 0.000 9 108/ 4832
add-spec-list-to-specifier 0/ 0 0.000 5 120/ 120
execute_internal_event() 0/ 3 0.000 21 0/ 11320
call-interactively 0/89487 0.000 3 36/444962623
image-instance-p 0/ 0 0.000 4
root-window->saved-window 0/ 1 0.000 12 0/ 6528
set-mark 0/ 0 0.000 1
remove 0/ 0 0.000 1 0/ 24
copy-sequence 0/ 0 0.000 9 324/ 324
paren-highlight 0/ 0 0.000 1
mapc 0/ 0 0.000 3 0/ 1200
pending-delete-pre-hook 0/ 0 0.000 2
event-frame 0/ 0 0.000 2
restore-saved-window 0/ 0 0.000 1
format 0/ 0 0.000 1 40/ 40
clearcase-ct-kill-buffer-hook 0/ 0 0.000 1
itimer-function 0/ 0 0.000 2
window-point 0/ 0 0.000 14
toolbar-button-p 0/ 0 0.000 2
event-over-modeline-p 0/ 0 0.000 2
key-press-event-p 0/ 0 0.000 3
set-itimer-value-internal 0/ 0 0.000 11
get-selection-internal 0/ 0 0.000 1 0/ 36
walk-windows 0/ 67 0.000 4
itimer-time-difference 0/ 0 0.000 36 2304/ 2304
valid-specifier-locale-p 0/ 0 0.000 5
event-point 0/ 0 0.000 4
blink-cursor-post-command-hook 0/ 0 0.000 1 0/ 236
point-max 0/ 0 0.000 1
profile-command 0/89487 0.000 0/444962623
lazy-lock-pre-idle-fontify-windows 0/ 67 0.000 23
extent-live-p 0/ 0 0.000 2
minibuffer-depth 0/ 0 0.000 4
lazy-lock-fontify-region 0/ 0 0.000 1
compilation-mode-motion-hook 0/ 2 0.000 2 0/ 5328
equal 0/ 0 0.000 2
current-window-configuration 0/ 1 0.000 6 0/ 7992
set-window-point 0/ 0 0.000 9
eq 0/ 0 0.000 1
byte-code 0/ 114 0.000 47 32/ 15564
event-type 0/ 0 0.000 3
buffer-string 0/ 0 0.000 1 0/ 64
apply 0/ 0 0.000 4 0/ 40
set-buffer-dedicated-frame 0/ 0 0.000 1 24/ 24
start-profiling 0/ 0 0.000 -12/ -12
frame-modified-tick 0/ 0 0.000 23
make-marker 0/ 0 0.000 24 576/ 576
next-window 0/ 0 0.000 8
itimer-is-idle 0/ 0 0.000 81
glyphp 0/ 0 0.000 2
unwind-protect 0/ 57 0.000 1 0/ 326345
buffer-name 0/ 0 0.000 1
specifier-type 0/ 0 0.000 10
pending-delete-active-region 0/ 0 0.000 1
read-from-minibuffer 0/ 115 0.000 1 12/ 17688
funcall 0/ 1 0.000 4
handle-post-motion-command 0/ 0 0.000 1 0/ 540
execute-extended-command 0/89487 0.000 0/444962623
set-modeline-hscroll 0/ 0 0.000 1
default-boundp 0/ 0 0.000 1
recursion-depth 0/ 0 0.000 1
buffer-live-p 0/ 0 0.000 2
select-frame 0/ 0 0.000 8
#<compiled-function nil "...(102)" [minibuffer-completion-predicate
minibuffer-confirm-incomplete completion minibuffer-completion-table event buffer-string
throw exit nil exact-minibuffer-completion-p t try-completion temp-minibuffer-message
[incomplete; confirm] [no completions; confirm] next-command-event quit-char
event-to-character dispatch-event inhibit-quit quit-flag last-command-event] 5
(c:\progra~1\xemacs\XEmacs-21.5-b19\lisp\minibuf.elc . 17959) nil>
0/ 0 0.000 1 0/ -24
call-with-condition-handler 0/ 0 0.000 23
yank 0/ 1 0.000 1 72/ 156
pointer-image-instance-p 0/ 0 0.000 4
select-buffer-killed-text 0/ 0 0.000 1
console-type 0/ 0 0.000 18
save-current-buffer 0/ 56 0.000 1 0/ 326177
set-window-configuration 0/ 2 0.000 3 0/ 3996
frame-root-window 0/ 0 0.000 32
throw 0/ 0 0.000 29 -24/ -24
event-modifiers 0/ 0 0.000 3 24/ 24
window-first-hchild 0/ 0 0.000 13
hash-table-count 0/ 0 0.000 23
nuke-selective-display 0/ 0 0.000 1
operate-on-matching-lines 0/89370 0.000 1 0/444944823
itimer-value 0/ 0 0.000 101
canonicalize-spec-list 0/ 0 0.000 5 60/ 1000
auto-show-should-take-action-p 0/ 0 0.000 1
clear-message 0/ 0 0.000 6
marker-position 0/ 0 0.000 4
run-hook-with-args 0/ 2 0.000 3 0/ 5328
fboundp 0/ 0 0.000 3
buffer-disable-undo 0/ 0 0.000 1
erc-kill-buffer-function 0/ 0 0.000 1 0/ 72
make-window-configuration 0/ 0 0.000 6 1152/ 1464
extentp 0/ 0 0.000 3
frame-properties 0/ 0 0.000 1 216/ 216
fw-frame 0/ 0 0.000 2
kill-new 0/ 0 0.000 1 12/ 12
bufferp 0/ 0 0.000 2
let 0/89370 0.000 3 0/444944639
use-local-map 0/ 0 0.000 1
device-type 0/ 0 0.000 9
get-buffer 0/ 0 0.000 9
itimer-function-arguments 0/ 0 0.000 2
copy-marker 0/ 0 0.000 13 312/ 312
window-frame 0/ 0 0.000 26
browse-url-delete-temp-file 0/ 0 0.000 1
resize-minibuffer-window 0/ 0 0.000 2 0/ 64
valid-specifier-tag-p 0/ 0 0.000 5
window-buffer 0/ 0 0.000 34
raw-append-message 0/ 2 0.000 1
read-minibuffer-internal 0/ 112 0.000 1 104/ 14232
framep 0/ 0 0.000 6
cperl-lazy-hook 0/ 0 0.000 1 24/ 24
window-truncated-p 0/ 0 0.000 1
blink-cursor-callback 0/ 0 0.000 8 0/ 1160
current-time 0/ 0 0.000 26 936/ 936
point-min 0/ 0 0.000 1
handle-pre-motion-command 0/ 0 0.000 2 0/ 684
message 0/ 2 0.000 2 12/ 76
auto-show-make-point-visible 0/ 0 0.000 1
event-over-toolbar-p 0/ 0 0.000 2
symbol-value-in-buffer 0/ 0 0.000 10
font-lock-pre-idle-hook 0/ 0 0.000 23
markerp 0/ 0 0.000 1
selected-window 0/ 0 0.000 46
get-clipboard 0/ 0 0.000 1 0/ 36
command-execute 0/89487 0.000 0/444962623
iso-acc-minibuf-setup 0/ 0 0.000 1 24/ 24
delay-uniquify-rationalize-file-buffer-names
0/ 0 0.000 1
#<compiled-function (&rest forms) "...(27)" [forms temp-buffer
make-symbol temp-buffer let ((get-buffer-create (generate-new-buffer-name *temp*)))
unwind-protect with-current-buffer and buffer-name kill-buffer] 8 699183>
0/ 0 0.000 1 228/ 252
enlarge-window-pixels 0/ 0 0.000 1
remove-message 0/ 0 0.000 6
frame-reduce-to-one-window 0/ 0 0.000 1
frame-type 0/ 0 0.000 9
quote 0/ 0 0.000 2
#<compiled-function nil "...(10)" [font-lock-pending-buffer-table
hash-table-count 0 font-lock-fontify-pending-extents] 2>
0/ 0 0.000 23
window-start 0/ 0 0.000 16
itimer-recorded-run-time 0/ 0 0.000 18
vectorp 0/ 0 0.000 9
itimer-run-expired-timers 0/ 0 0.000 9 1296/ 3824
local-variable-p 0/ 0 0.000 2
with-temp-buffer 0/ 57 0.000 1 0/ 327669
canonicalize-inst-list 0/ 0 0.000 10 60/ 880
boundp 0/ 0 0.000 14
display-message 0/ 2 0.000 1 0/ 24
specifierp 0/ 0 0.000 2
buffer-modified-tick 0/ 0 0.000 4
copy-keymap 0/ 0 0.000 1 528/ 528
#<compiled-function (string regexp-flag &rest body) "...(18)" [body
regexp-flag string let case-fold-search if (and case-fold-search
search-caps-disable-folding) no-upper-case-p (case-fold-search)] 7 942133>
0/ 0 0.000 1 184/ 184
get-selection 0/ 0 0.000 1 0/ 36
fmakunbound 0/ 0 0.000 3
glyph-property-instance 0/ 0 0.000 2
event-modeline-position 0/ 0 0.000 2
paren-nuke-extent 0/ 0 0.000 2
select-buffer-killed-default 0/ 0 0.000 1
select-coerce 0/ 0 0.000 1 36/ 36
set-window-dedicated-p 0/ 0 0.000 1
local-variable-if-set-p 0/ 0 0.000 1
set-window-buffer 0/ 0 0.000 2
event-window 0/ 0 0.000 10
current-kill 0/ 0 0.000 1 0/ 48
handle-pre-motion-command-current-command-is-motion
0/ 0 0.000 3 0/ 1224
device-console 0/ 0 0.000 9
set-buffer 0/ 0 0.000 1
really-set-window-configuration 0/ 1 0.000 1
glyph-image-instance 0/ 0 0.000 2
event-key 0/ 0 0.000 3
window-first-vchild 0/ 0 0.000 13
featurep 0/ 0 0.000 4
make-symbol 0/ 0 0.000 1 24/ 24
insert-string 0/ 0 0.000 1
event-channel 0/ 0 0.000 2
get-buffer-create 0/ 0 0.000 1 1072/ 1072
#<compiled-function (keysym) "...(31)" [mods key keysym butlast keysyms-equal
last throw handle-pre-motion-command-current-command-is-motion t] 4>
0/ 0 0.000 72 0/ 1200
select-coerce-to-text 0/ 0 0.000 1
set-frame-pointer 0/ 0 0.000 2
set-specifier 0/ 0 0.000 5 60/ 1180
input-pending-p 0/ 0 0.000 1
marker-buffer 0/ 0 0.000 1
lazy-lock-fontify-after-defer 0/ 0 0.000 2
push-mark 0/ 1 0.000 1 12/ 36
noninteractive 0/ 0 0.000 1
lazy-lock-vertical-motion-value 0/ 43 0.000 4
frame-pixel-height 0/ 0 0.000 6
frame-minibuffer-only-p 0/ 0 0.000 23
keysyms-equal 0/ 0 0.000 48 0/ 768
next-single-property-change 0/ 0 0.000 1
saved-window-equal 0/ 0 0.000 4
set-buffer-modified-p 0/ 0 0.000 1
character-to-event 0/ 0 0.000 1
set-itimer-recorded-run-time 0/ 0 0.000 2
window-hscroll 0/ 0 0.000 12
char-to-string 0/ 0 0.000 32 768/ 768
window-height 0/ 0 0.000 2
disable-timeout 0/ 0 0.000 9 -108/ -108
valid-specifier-tag-set-p 0/ 0 0.000 5
#<subr when> 0/ 0 0.000 3 144/ 144
buffer-size 0/ 0 0.000 3
decode-buffer 0/ 0 0.000 4
intern 0/ 0 0.000 32
window-pixel-height 0/ 0 0.000 7
minibuffer-window 0/ 0 0.000 45
stop-profiling 0/ 0 0.000 1
buffer-enable-undo 0/ 0 0.000 1
text-property-any 0/ 0 0.000 1
with-search-caps-disable-folding 0/89370 0.000 1 0/444944823
run-finalizers 0/ 0 0.000 87
cleanup-simple-finalizers 0/ 0 0.000 87
add-hook 0/ 0 0.000 1 12/ 12
select-window 0/ 0 0.000 3
window-configuration-equal 0/ 0 0.000 3
characterp 0/ 0 0.000 97
frame-live-p 0/ 0 0.000 12
itimer-uses-arguments 0/ 0 0.000 2
event-toolbar-button 0/ 0 0.000 2
gutter-pixel-width 0/ 0 0.000 6
window-pixel-edges 0/ 0 0.000 12 576/ 576
enlarge-window 0/ 0 0.000 1
store-match-data 0/ 0 0.000 2
resize-minibuffer-setup 0/ 0 0.000 1 0/ 264
itimer-disable-timeout 0/ 0 0.000 9 0/ -108
canonicalize-inst-pair 0/ 0 0.000 15 60/ 820
select-convert-to-text 0/ 0 0.000 1
append-message 0/ 2 0.000 1 24/ 24
help-keymap-with-help-key 0/ 0 0.000 1 0/ 548
#<compiled-function (buffer &rest body) "...(8)" [body buffer
save-current-buffer set-buffer] 3 698228>
0/ 0 0.000 1 72/ 72
event-over-vertical-divider-p 0/ 0 0.000 2
mark 0/ 1 0.000 1
string-match 0/ 0 0.000 1 44/ 44
#<compiled-function (regexp) "...(39)" [regexp beg end count nil
region-active-p zmacs-region-buffer region-beginning region-end operate-on-matching-lines
t message %i lines deleted] 6 726484 (list (read-from-minibuffer Flush lines (containing
match for regexp): nil nil nil (quote regexp-history)))>
0/89372 0.000 1 0/444944899
event-glyph-extent 0/ 0 0.000 2
crypt-forget-encryption-key 0/ 0 0.000 1
make-local-hook 0/ 0 0.000 1 12/ 36
set-window-start 0/ 0 0.000 1
when 0/ 0 0.000 3 0/ 144
frame-visible-p 0/ 0 0.000 23
no-upper-case-p 0/ 0 0.000 1 0/ 44
windowp 0/ 0 0.000 10
next-frame 0/ 0 0.000 23
event-live-p 0/ 0 0.000 3
set-window-configuration-frame-size 0/ 1 0.000 1
frame-device 0/ 0 0.000 9
mapc-internal 0/ 0 0.000 3 0/ 1200
resize-minibuffer-count-window-lines 0/ 0 0.000 2 0/ 64
mode-motion-ensure-extent-ok 0/ 0 0.000 2
kill-all-local-variables 0/ 0 0.000 1
remove* 0/ 0 0.000 1 24/ 24
list 0/ 0 0.000 1 12/ 12
selected-frame 0/ 0 0.000 38
window-next-child 0/ 0 0.000 18
window-minibuffer-p 0/ 0 0.000 4
extent-at 0/ 0 0.000 8
specifier-instance 0/ 0 0.000 10
delq 0/ 0 0.000 3
match-data 0/ 0 0.000 2 48/ 48
image-instance-type 0/ 0 0.000 2
current-message-label 0/ 0 0.000 4
add-timeout 0/ 0 0.000 9 108/ 108
canonicalize-spec 0/ 0 0.000 5 60/ 940
modeline-hscroll 0/ 0 0.000 12
region-active-p 0/ 0 0.000 2
last 0/ 0 0.000 12
make-local-variable 0/ 0 0.000 6 144/ 144
generate-new-buffer-name 0/ 0 0.000 1
valid-instantiator-p 0/ 0 0.000 20 760/ 760
itimerp 0/ 0 0.000 223
lazy-lock-maybe-fontify-frame 0/ 67 0.000 23
default-mouse-motion-handler 0/ 3 0.000 2 0/ 5328
highlight-extent 0/ 0 0.000 2
detach-extent 0/ 0 0.000 2
frame-pixel-width 0/ 0 0.000 6
set-window-hscroll 0/ 0 0.000 2
butlast 0/ 0 0.000 36 432/ 432
maybe-saved-window-equal 0/ 0 0.000 12
extent-object 0/ 0 0.000 2
restore-saved-window-parameters 0/ 0 0.000 1
natnump 0/ 0 0.000 2
plist-get 0/ 0 0.000 1
-----------------------------------------------------------------------------
Total 89459 100.000 280583 444962623
Ticks/Total = Ticks this function/this function and descendants
Calls = Number of calls to this function
GC-Usage/Total = Lisp allocation this function/this function and descendants
One tick = 1 ms
Here is my reimplementation which executes in 1.9s (at same
gc-cons-threshold, which I will try to lower again now).
Function Name Ticks/Total %Usage Calls GC-Usage/ Total
=========================================/===== ====== ===== ========/=======
delete-region 483/ 967 25.354 6544 622040/1172116
(profile overhead) 454/ 454 23.832
(in map-extents-internal) 206/ 236 10.814 59007 733308/ 733308
append-to-buffer 172/ 379 9.029 6544 0/ 648148
re-search-forward 100/ 134 5.249 6545 68/ 68
insert-buffer-substring 90/ 166 4.724 6544 464916/ 648148
lazy-lock-after-change 65/ 218 3.412 6544 0/ 380
(in redisplay) 60/ 85 3.150 22 1216/ 1216
(in char-byte conversion) 55/ 59 2.887 509210
start-profiling 27/ 27 1.417 -12/ -12
vertical-motion 22/ 45 1.155 17 128/ 128
while 20/ 1722 1.050 1 0/1820332
save-excursion 20/ 1731 1.050 6545 0/2143763
lazy-lock-put-text-property 17/ 41 0.892 6544 0/ 380
(in internal-external conversion) 15/ 15 0.787 1931
window-end 13/ 27 0.682 15
and 8/ 151 0.420 6547 0/ 68
beginning-of-line 7/ 23 0.367 6546
point-at-bol 7/ 21 0.367 6544
forward-line 6/ 22 0.315 6544
setq 6/ 181 0.315 13090 0/ 322183
get-text-property 5/ 21 0.262 6545
buffer-substring 5/ 5 0.262 3 322215/ 322215
if 5/ 978 0.262 6549 0/1172160
progn 4/ 37 0.210 6544
next_event_internal() 4/ 4 0.210 22 112/ 112
match-beginning 4/ 4 0.210 6544
goto-char 4/ 10 0.210 6544
count-lines 3/ 3 0.157 1
get-buffer-create 2/ 2 0.105 6545 1080/ 1080
paren-nuke-extent 1/ 1 0.052 3
make-saved-window 1/ 1 0.052 12 4032/ 5088
set-frame-pixel-size 1/ 1 0.052 1
read-from-minibuffer 1/ 174 0.052 1 12/ 16852
point 1/ 1 0.052 13109
eobp 1/ 1 0.052 6545
copy-keymap 1/ 1 0.052 1 528/ 528
erase-buffer 1/ 1 0.052 12 112/ 112
kill-buffer 1/ 1 0.052 1 24/ 96
execute_internal_event() 1/ 3 0.052 19 0/ 8520
redisplay-echo-area 1/ 1 0.052 1
lazy-lock-vertical-motion-value 1/ 45 0.052 15
byte-code 1/ 171 0.052 56 0/ 14604
event-window 1/ 1 0.052 10
device-type 1/ 2 0.052 11
valid-instantiator-p 1/ 1 0.052 56 2128/ 2128
device-live-p 0/ 0 0.000 11
with-current-buffer 0/ 3 0.000 1 0/ 60
mode-motion-highlight-internal 0/ 1 0.000 2 0/ 5328
reset-buffer 0/ 0 0.000 1 0/ 48
dispatch-event 0/ 6 0.000 22 280/ 11552
vector 0/ 0 0.000 19 1388/ 1388
window-dedicated-p 0/ 0 0.000 12
gethash 0/ 0 0.000 112
not 0/ 0 0.000 6545
puthash 0/ 0 0.000 19
add-spec-list-to-specifier 0/ 0 0.000 14 336/ 336
mark-marker 0/ 0 0.000 14
call-interactively 0/ 1935 0.000 4 36/2160915
image-instance-p 0/ 0 0.000 4
root-window->saved-window 0/ 2 0.000 12 0/ 6528
remove 0/ 0 0.000 1 0/ 144
copy-sequence 0/ 0 0.000 1 12/ 12
paren-highlight 0/ 0 0.000 2
mapc 0/ 0 0.000 5 0/ 1872
pending-delete-pre-hook 0/ 0 0.000 3
event-frame 0/ 0 0.000 2
restore-saved-window 0/ 0 0.000 1
format 0/ 0 0.000 1 40/ 40
ldiff 0/ 0 0.000 1 12/ 12
clearcase-ct-kill-buffer-hook 0/ 0 0.000 1
window-point 0/ 0 0.000 36
toolbar-button-p 0/ 0 0.000 2
generate-new-buffer 0/ 0 0.000 1 0/ 1080
event-over-modeline-p 0/ 0 0.000 2
key-press-event-p 0/ 0 0.000 5
walk-windows 0/ 72 0.000 15
valid-specifier-locale-p 0/ 0 0.000 14
event-point 0/ 0 0.000 4
blink-cursor-post-command-hook 0/ 1 0.000 2 0/ 472
point-max 0/ 0 0.000 1
profile-command 0/ 1935 0.000 0/2160915
lazy-lock-pre-idle-fontify-windows 0/ 74 0.000 22
extent-live-p 0/ 0 0.000 2
minibuffer-depth 0/ 0 0.000 3
lazy-lock-fontify-region 0/ 0 0.000 1
compilation-mode-motion-hook 0/ 1 0.000 2 0/ 5328
equal 0/ 0 0.000 3
current-window-configuration 0/ 2 0.000 6 0/ 7992
set-window-point 0/ 0 0.000 31
eq 0/ 0 0.000 1
event-type 0/ 0 0.000 5
buffer-string 0/ 5 0.000 3 0/ 322215
apply 0/ 0 0.000 2 0/ 136
set-buffer-dedicated-frame 0/ 0 0.000 1 24/ 24
frame-modified-tick 0/ 0 0.000 22
make-marker 0/ 0 0.000 24 576/ 576
next-window 0/ 0 0.000 30
glyphp 0/ 0 0.000 2
specifier-type 0/ 0 0.000 28
next-event 0/ 164 0.000 22 0/ 1328
lazy-lock-fontify-window 0/ 72 0.000 30
funcall 0/ 0 0.000 4
handle-post-motion-command 0/ 0 0.000 2 0/ 888
execute-extended-command 0/ 1935 0.000 0/2160915
set-modeline-hscroll 0/ 0 0.000 1
default-boundp 0/ 0 0.000 1
recursion-depth 0/ 0 0.000 1
buffer-live-p 0/ 0 0.000 2
select-frame 0/ 0 0.000 30
#<compiled-function nil "...(102)" [minibuffer-completion-predicate
minibuffer-confirm-incomplete completion minibuffer-completion-table event buffer-string
throw exit nil exact-minibuffer-completion-p t try-completion temp-minibuffer-message
[incomplete; confirm] [no completions; confirm] next-command-event quit-char
event-to-character dispatch-event inhibit-quit quit-flag last-command-event] 5
(c:\progra~1\xemacs\XEmacs-21.5-b19\lisp\minibuf.elc . 17959) nil>
0/ 0 0.000 1 0/ -24
event-buffer 0/ 0 0.000 8
call-with-condition-handler 0/ 0 0.000 22
pointer-image-instance-p 0/ 0 0.000 4
select-buffer-killed-text 0/ 0 0.000 1
console-type 0/ 0 0.000 27
save-current-buffer 0/ 3 0.000 1
set-window-configuration 0/ 2 0.000 3 0/ 3996
frame-root-window 0/ 0 0.000 31
throw 0/ 0 0.000 37 -24/ -24
event-modifiers 0/ 0 0.000 5 48/ 48
window-first-hchild 0/ 0 0.000 13
hash-table-count 0/ 0 0.000 22
nuke-selective-display 0/ 0 0.000 1
operate-on-matching-lines 0/ 1731 0.000 1 0/2143951
canonicalize-spec-list 0/ 1 0.000 14 168/ 2800
#<compiled-function nil "...(52)" [compilation-old-error-list
compilation-parsing-end compilation-mouse-motion-initiate-parsing e compilation-error-list
p nil t ((compile-reinitialize-errors nil p)) found (byte-code «¤Ä@@!© W«¥Aª±
X«§ÅÆÇ"¨ª¥ÅÆÈ"¨)ªYȧ [e p x l marker-position throw found t nil] 4) l] 2>
0/ 0 0.000 2
auto-show-should-take-action-p 0/ 0 0.000 2
clear-message 0/ 2 0.000 8
marker-position 0/ 0 0.000 3
run-hook-with-args 0/ 1 0.000 2 0/ 5328
fboundp 0/ 0 0.000 5
buffer-disable-undo 0/ 0 0.000 1
erc-kill-buffer-function 0/ 0 0.000 1 0/ 72
make-window-configuration 0/ 0 0.000 6 1152/ 1464
extentp 0/ 0 0.000 3
frame-properties 0/ 0 0.000 1 216/ 216
fw-frame 0/ 0 0.000 2
bufferp 0/ 0 0.000 5
let 0/ 1731 0.000 2 0/2143807
use-local-map 0/ 0 0.000 1
copy-marker 0/ 0 0.000 12 288/ 288
window-frame 0/ 0 0.000 26
browse-url-delete-temp-file 0/ 0 0.000 1
resize-minibuffer-window 0/ 1 0.000 3 0/ 128
valid-specifier-tag-p 0/ 0 0.000 14
window-buffer 0/ 0 0.000 67
raw-append-message 0/ 1 0.000 1
read-minibuffer-internal 0/ 170 0.000 1 104/ 13272
framep 0/ 0 0.000 17
cperl-lazy-hook 0/ 0 0.000 2 24/ 24
window-truncated-p 0/ 0 0.000 2
blink-cursor-callback 0/ 0 0.000 15 0/ 3192
current-time 0/ 0 0.000 10 360/ 360
point-min 0/ 0 0.000 1
handle-pre-motion-command 0/ 0 0.000 3 0/ 1032
message 0/ 3 0.000 2 12/ 76
auto-show-make-point-visible 0/ 0 0.000 2
event-over-toolbar-p 0/ 0 0.000 2
symbol-value-in-buffer 0/ 0 0.000 32
font-lock-pre-idle-hook 0/ 0 0.000 22
markerp 0/ 0 0.000 1
selected-window 0/ 0 0.000 87
command-execute 0/ 1935 0.000 0/2160915
iso-acc-minibuf-setup 0/ 0 0.000 1 24/ 24
delay-uniquify-rationalize-file-buffer-names
0/ 0 0.000 1
enlarge-window-pixels 0/ 0 0.000 1
remove-message 0/ 0 0.000 8
delete* 0/ 0 0.000 1 96/ 96
frame-reduce-to-one-window 0/ 0 0.000 1
frame-type 0/ 2 0.000 11
quote 0/ 0 0.000 2
#<compiled-function nil "...(10)" [font-lock-pending-buffer-table
hash-table-count 0 font-lock-fontify-pending-extents] 2>
0/ 0 0.000 22
window-start 0/ 0 0.000 27
local-variable-p 0/ 0 0.000 2
canonicalize-inst-list 0/ 1 0.000 28 168/ 2464
boundp 0/ 0 0.000 5
display-message 0/ 3 0.000 1 0/ 24
specifierp 0/ 0 0.000 2
buffer-modified-tick 0/ 0 0.000 15
#<compiled-function (string regexp-flag &rest body) "...(18)" [body
regexp-flag string let case-fold-search if (and case-fold-search
search-caps-disable-folding) no-upper-case-p (case-fold-search)] 7 942133>
0/ 0 0.000 1 144/ 144
fmakunbound 0/ 0 0.000 5
glyph-property-instance 0/ 0 0.000 2
event-modeline-position 0/ 0 0.000 2
select-buffer-killed-default 0/ 0 0.000 1
set-window-dedicated-p 0/ 0 0.000 1
previous-history-element 0/ 0 0.000 2 0/ 232
local-variable-if-set-p 0/ 0 0.000 1
set-window-buffer 0/ 0 0.000 2
handle-pre-motion-command-current-command-is-motion
0/ 0 0.000 5 0/ 1920
device-console 0/ 0 0.000 11
set-buffer 0/ 0 0.000 1
really-set-window-configuration 0/ 1 0.000 1
glyph-image-instance 0/ 0 0.000 2
event-key 0/ 0 0.000 5
window-first-vchild 0/ 0 0.000 13
featurep 0/ 0 0.000 4
insert-string 0/ 0 0.000 1
event-channel 0/ 0 0.000 2
#<compiled-function (keysym) "...(31)" [mods key keysym butlast keysyms-equal
last throw handle-pre-motion-command-current-command-is-motion t] 4>
0/ 0 0.000 120 0/ 1872
set-frame-pointer 0/ 0 0.000 2
set-specifier 0/ 1 0.000 14 168/ 3304
input-pending-p 0/ 0 0.000 2
noninteractive 0/ 0 0.000 1
frame-pixel-height 0/ 0 0.000 6
frame-minibuffer-only-p 0/ 0 0.000 22
keysyms-equal 0/ 0 0.000 64 0/ 1152
next-single-property-change 0/ 0 0.000 1
saved-window-equal 0/ 0 0.000 4
set-buffer-modified-p 0/ 0 0.000 1
character-to-event 0/ 0 0.000 1
window-hscroll 0/ 0 0.000 12
char-to-string 0/ 0 0.000 48 1152/ 1152
window-height 0/ 0 0.000 3
valid-specifier-tag-set-p 0/ 0 0.000 14
#<subr when> 0/ 0 0.000 3 144/ 144
buffer-size 0/ 0 0.000 4
decode-buffer 0/ 0 0.000 1
intern 0/ 0 0.000 48
window-pixel-height 0/ 0 0.000 7
minibuffer-window 0/ 0 0.000 44
stop-profiling 0/ 0 0.000 1
buffer-enable-undo 0/ 0 0.000 1
text-property-any 0/ 0 0.000 1
with-search-caps-disable-folding 0/ 1731 0.000 1 0/2143951
add-hook 0/ 0 0.000 1 12/ 12
select-window 0/ 0 0.000 3
window-configuration-equal 0/ 0 0.000 3
characterp 0/ 0 0.000 129
frame-live-p 0/ 0 0.000 14
event-toolbar-button 0/ 0 0.000 2
gutter-pixel-width 0/ 0 0.000 6
window-pixel-edges 0/ 0 0.000 12 576/ 576
enlarge-window 0/ 0 0.000 1
resize-minibuffer-setup 0/ 0 0.000 1 0/ 264
canonicalize-inst-pair 0/ 1 0.000 42 168/ 2296
append-message 0/ 2 0.000 1 24/ 24
help-keymap-with-help-key 0/ 1 0.000 1 0/ 548
#<compiled-function (buffer &rest body) "...(8)" [body buffer
save-current-buffer set-buffer] 3 698228>
0/ 0 0.000 1 60/ 60
event-over-vertical-divider-p 0/ 0 0.000 2
string-match 0/ 0 0.000 1 44/ 44
#<compiled-function (regexp) "...(39)" [regexp beg end count nil
region-active-p zmacs-region-buffer region-beginning region-end operate-on-matching-lines
t message %i lines deleted] 6 726484 (list (read-from-minibuffer Flush lines (containing
match for regexp): nil nil nil (quote regexp-history)))>
0/ 1734 0.000 1 0/2144027
event-glyph-extent 0/ 0 0.000 2
crypt-forget-encryption-key 0/ 0 0.000 1
make-local-hook 0/ 0 0.000 1 12/ 36
set-window-start 0/ 0 0.000 1
when 0/ 0 0.000 3 0/ 144
frame-visible-p 0/ 0 0.000 22
no-upper-case-p 0/ 0 0.000 1 0/ 44
windowp 0/ 0 0.000 10
next-frame 0/ 0 0.000 22
event-live-p 0/ 0 0.000 5
set-window-configuration-frame-size 0/ 1 0.000 1
frame-device 0/ 0 0.000 11
mapc-internal 0/ 0 0.000 5 0/ 1872
resize-minibuffer-count-window-lines 0/ 1 0.000 3 0/ 128
mode-motion-ensure-extent-ok 0/ 0 0.000 2
kill-all-local-variables 0/ 0 0.000 1
remove* 0/ 0 0.000 1 24/ 144
list 0/ 0 0.000 1 12/ 12
selected-frame 0/ 0 0.000 48
next-history-element 0/ 0 0.000 2 96/ 232
window-next-child 0/ 0 0.000 18
window-minibuffer-p 0/ 0 0.000 15
extent-at 0/ 0 0.000 8
specifier-instance 0/ 0 0.000 17
delq 0/ 0 0.000 5
image-instance-type 0/ 0 0.000 2
current-message-label 0/ 0 0.000 6
canonicalize-spec 0/ 1 0.000 14 168/ 2632
modeline-hscroll 0/ 0 0.000 12
last 0/ 0 0.000 4
region-active-p 0/ 0 0.000 1
make-local-variable 0/ 0 0.000 6 144/ 144
generate-new-buffer-name 0/ 0 0.000 1
lazy-lock-maybe-fontify-frame 0/ 73 0.000 22
default-mouse-motion-handler 0/ 2 0.000 2 0/ 5328
highlight-extent 0/ 0 0.000 2
detach-extent 0/ 0 0.000 2
frame-pixel-width 0/ 0 0.000 6
set-window-hscroll 0/ 0 0.000 2
butlast 0/ 0 0.000 60 720/ 720
maybe-saved-window-equal 0/ 0 0.000 12
extent-object 0/ 0 0.000 2
restore-saved-window-parameters 0/ 0 0.000 1
natnump 0/ 0 0.000 4
plist-get 0/ 0 0.000 1
-----------------------------------------------------------------------------
Total 1905 100.000 723370 2160915
Ticks/Total = Ticks this function/this function and descendants
Calls = Number of calls to this function
GC-Usage/Total = Lisp allocation this function/this function and descendants
One tick = 1 ms
I intend to commit this in a few days and would be greatful for review and testing.
Best regards,
Adrian
lisp/ChangeLog addition:
2005-02-20 Adrian Aichner <adrian(a)xemacs.org>
* replace.el (operate-on-non-matching-lines): Append matching
lines to temp buffer to avoid prohibitive GC as a result of
enormous string consing.
* replace.el (operate-on-matching-lines): Ditto.
* replace.el (delete-non-matching-lines): Honor region only when
active in current buffer.
* replace.el (kill-non-matching-lines): Ditto.
* replace.el (copy-non-matching-lines): Ditto.
* replace.el (delete-matching-lines): Ditto.
* replace.el (kill-matching-lines): Ditto.
* replace.el (copy-matching-lines): Ditto.
* replace.el (perform-replace): Ditto.
Index: replace.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lisp/replace.el,v
retrieving revision 1.10
diff -u -u -r1.10 replace.el
--- replace.el 12 May 2003 05:12:10 -0000 1.10
+++ replace.el 20 Feb 2005 22:06:59 -0000
@@ -247,7 +247,9 @@
(let ((matched-text nil)
(curmatch-start (point))
- (limit (copy-marker (point-max))))
+ (limit (copy-marker (point-max)))
+ (matched-text-buffer (generate-new-buffer " *matched-text*"))
+ lines-matched)
;; Limit search if limits were specified.
(when end (setq limit (copy-marker end)))
@@ -259,32 +261,33 @@
;; curmatch-start is first char not preserved by previous match.
(if (not (re-search-forward regexp limit 'move))
(let ((curmatch-end limit))
- (setq matched-text (concat matched-text (buffer-substring curmatch-start
curmatch-end)))
+ (append-to-buffer matched-text-buffer curmatch-start curmatch-end)
(if delete (delete-region curmatch-start curmatch-end)))
(let ((curmatch-end (save-excursion (goto-char (match-beginning 0))
- (beginning-of-line)
- (point))))
+ (beginning-of-line)
+ (point))))
;; Now curmatch-end is first char preserved by the new match.
(if (< curmatch-start curmatch-end)
(progn
- (setq matched-text (concat matched-text (buffer-substring
curmatch-start curmatch-end)))
+ (append-to-buffer matched-text-buffer curmatch-start curmatch-end)
(if delete (delete-region curmatch-start curmatch-end))))))
(setq curmatch-start (save-excursion (forward-line 1)
- (point)))
+ (point)))
;; If the match was empty, avoid matching again at same place.
(and (not (eobp)) (= (match-beginning 0) (match-end 0))
(forward-char 1)))
;; If any lines were matched and KILL is non-nil, insert the
;; matched lines into the kill ring.
+ (setq matched-text (buffer-string matched-text-buffer))
(if (and matched-text kill) (kill-new matched-text))
;; Return the number of matched lines.
- (with-temp-buffer
- ;; Use concat to make a string even if matched-text is nil.
- (insert (concat matched-text))
- (count-lines (point-min) (point-max)))
- ))))
+ (setq lines-matched
+ (with-current-buffer matched-text-buffer
+ (count-lines (point-min) (point-max))))
+ (kill-buffer matched-text-buffer)
+ lines-matched))))
(define-function 'keep-lines 'delete-non-matching-lines)
(defun delete-non-matching-lines (regexp)
@@ -296,7 +299,8 @@
(let ((beg nil)
(end nil)
(count nil))
- (when (region-active-p)
+ (when (and (region-active-p)
+ (eq (current-buffer) (zmacs-region-buffer)))
(setq beg (region-beginning))
(setq end (region-end)))
(setq count (operate-on-non-matching-lines regexp t nil beg end))
@@ -313,7 +317,8 @@
(let ((beg nil)
(end nil)
(count nil))
- (when (region-active-p)
+ (when (and (region-active-p)
+ (eq (current-buffer) (zmacs-region-buffer)))
(setq beg (region-beginning))
(setq end (region-end)))
(setq count (operate-on-non-matching-lines regexp t t beg end))
@@ -330,7 +335,8 @@
(let ((beg nil)
(end nil)
(count nil))
- (when (region-active-p)
+ (when (and (region-active-p)
+ (eq (current-buffer) (zmacs-region-buffer)))
(setq beg (region-beginning))
(setq end (region-end)))
(setq count (operate-on-non-matching-lines regexp nil t beg end))
@@ -358,8 +364,9 @@
(let ((matched-text nil)
(curmatch-start nil)
(curmatch-end nil)
- (limit nil))
-
+ (limit nil)
+ (matched-text-buffer (generate-new-buffer " *matched-text*"))
+ lines-matched)
;; Limit search if limits were specified.
(when beg (goto-char beg))
(when end (setq limit (copy-marker end)))
@@ -370,17 +377,17 @@
(beginning-of-line)
(point)))
(setq curmatch-end (progn (forward-line 1) (point)))
- (setq matched-text (concat matched-text (buffer-substring curmatch-start
curmatch-end)))
+ (append-to-buffer matched-text-buffer curmatch-start curmatch-end)
(if delete (delete-region curmatch-start curmatch-end)))
-
+ (setq matched-text (buffer-string matched-text-buffer))
(if (and matched-text kill) (kill-new matched-text))
;; Return the number of matched lines.
- (with-temp-buffer
- ;; Use concat to make a string even if matched-text is nil.
- (insert (concat matched-text))
- (count-lines (point-min) (point-max)))
- ))))
+ (setq lines-matched
+ (with-current-buffer matched-text-buffer
+ (count-lines (point-min) (point-max))))
+ (kill-buffer matched-text-buffer)
+ lines-matched))))
(define-function 'flush-lines 'delete-matching-lines)
(defun delete-matching-lines (regexp)
@@ -392,7 +399,8 @@
(let ((beg nil)
(end nil)
(count nil))
- (when (region-active-p)
+ (when (and (region-active-p)
+ (eq (current-buffer) (zmacs-region-buffer)))
(setq beg (region-beginning))
(setq end (region-end)))
(setq count (operate-on-matching-lines regexp t nil beg end))
@@ -409,7 +417,8 @@
(let ((beg nil)
(end nil)
(count nil))
- (when (region-active-p)
+ (when (and (region-active-p)
+ (eq (current-buffer) (zmacs-region-buffer)))
(setq beg (region-beginning))
(setq end (region-end)))
(setq count (operate-on-matching-lines regexp t t beg end))
@@ -426,7 +435,8 @@
(let ((beg nil)
(end nil)
(count nil))
- (when (region-active-p)
+ (when (and (region-active-p)
+ (eq (current-buffer) (zmacs-region-buffer)))
(setq beg (region-beginning))
(setq end (region-end)))
(setq count (operate-on-matching-lines regexp nil t beg end))
@@ -831,7 +841,8 @@
(substitute-command-keys
"Query replacing %s with %s: (\\<query-replace-map>\\[help] for help)
"))))
;; If the region is active, operate on region.
- (when (region-active-p)
+ (when (and (region-active-p)
+ (eq (current-buffer) (zmacs-region-buffer)))
;; Original Per Abrahamsen's code simply narrowed the region,
;; thus providing a visual indication of the search boundary.
;; Stallman, on the other hand, handles it like this.
--
Adrian Aichner
mailto:adrian@xemacs.org
http://www.xemacs.org/