From: Raffael Stocker <r.stocker@mnet-mail.de>
To: 67536@debbugs.gnu.org
Subject: bug#67536: 29.1; Calc mode's math-read-preprocess-string conses unnecessarily
Date: Wed, 29 Nov 2023 22:29:38 +0100 [thread overview]
Message-ID: <yplm5y1k8cye.fsf@mnet-mail.de> (raw)
Org table re-calculation is very slow, partly due to
math-read-preprocess-string of calc mode consing unnecessarily. For
example, in one (large) table, I get the following memory usage from the
profiler:
...
60,252,646 96% - org-ctrl-c-ctrl-c
60,248,166 96% - org-table-calc-current-TBLFM
60,216,431 96% - funcall-interactively
60,205,119 96% - org-table-recalculate
49,094,651 78% - org-table-eval-formula
32,624,631 52% - calc-eval
32,624,631 52% - calc-do-calc-eval
32,620,487 52% - calc-do-calc-eval
32,611,151 52% - math-read-exprs
29,388,838 47% + math-read-preprocess-string
2,343,257 3% + math-read-expr-list
...
The reason for the slow-down seems to be that
math-read-preprocess-string conses a lot, keeping the GC busy. This is
due to heavy use of replace-regexp-in-string in this function:
(defun math-read-preprocess-string (str)
"Replace some substrings of STR by Calc equivalents."
(setq str
(replace-regexp-in-string (concat "[" math-read-superscripts "]+")
"^(\\&)" str))
(setq str
(replace-regexp-in-string (concat "[" math-read-subscripts "]+")
"_(\\&)" str))
(let ((rep-list math-read-replacement-list))
(while rep-list
;; consing like a mad-man here:
(setq str
(replace-regexp-in-string (nth 0 (car rep-list))
(nth 1 (car rep-list)) str))
(setq rep-list (cdr rep-list))))
str)
I would like to propose using a temp buffer instead of kneading the
string into submission:
(defun math-read-preprocess-string (str)
"Replace some substrings of STR by Calc equivalents."
(with-temp-buffer
(insert str)
(goto-char 0)
(while (re-search-forward (concat "[" math-read-superscripts "]+") nil t)
(replace-match "^(\\&)"))
(goto-char 0)
(while (re-search-forward (concat "[" math-read-subscripts "]+") nil t)
(replace-match "_(\\&)"))
(goto-char 0)
(let ((rep-list math-read-replacement-list))
(while rep-list
(while (re-search-forward (nth 0 (car rep-list)) nil t)
(replace-match (nth 1 (car rep-list))))
(goto-char 0)
(setq rep-list (cdr rep-list))))
(buffer-string)))
With this replacement, the profiler shows much less memory usage on the
same org table:
...
30,411,804 91% - org-ctrl-c-ctrl-c
30,407,324 91% - org-table-calc-current-TBLFM
30,363,932 91% - funcall-interactively
30,331,900 91% - org-table-recalculate
20,430,223 61% - org-table-eval-formula
6,751,852 20% + org-table-justify-field-maybe
4,598,523 13% - calc-eval
4,586,091 13% - calc-do-calc-eval
4,569,619 13% - calc-do-calc-eval
4,547,971 13% - math-read-exprs
2,297,453 6% + math-read-expr-list
1,347,377 4% + math-read-preprocess-string
7,296 0% math-read-token
...
Only I am not sure the replacement is correct in all possible edge cases
(or whether it uses so much less memory because I have overlooked
something).
What do you think? Can a calc-mode expert weigh in here?
Regards,
Raffael
next reply other threads:[~2023-11-29 21:29 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-29 21:29 Raffael Stocker [this message]
2023-11-30 7:00 ` bug#67536: 29.1; Calc mode's math-read-preprocess-string conses unnecessarily Eli Zaretskii
2023-11-30 18:28 ` Raffael Stocker
2023-11-30 19:14 ` Eli Zaretskii
2023-12-01 17:34 ` Raffael Stocker
2023-12-01 18:12 ` Eli Zaretskii
2023-12-01 21:10 ` Raffael Stocker
2023-12-02 8:03 ` Eli Zaretskii
2023-12-02 14:56 ` Mattias Engdegård
2023-12-02 19:26 ` Raffael Stocker
2023-12-03 10:43 ` Mattias Engdegård
2023-12-03 11:13 ` Raffael Stocker
2023-12-03 11:58 ` Mattias Engdegård
2023-12-05 18:14 ` Raffael Stocker
2023-12-16 9:40 ` Eli Zaretskii
2023-12-18 10:55 ` Mattias Engdegård
2023-12-18 11:39 ` Raffael Stocker
2023-12-19 16:16 ` Mattias Engdegård
2023-12-19 17:09 ` Raffael Stocker
2023-12-19 18:15 ` Mattias Engdegård
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=yplm5y1k8cye.fsf@mnet-mail.de \
--to=r.stocker@mnet-mail.de \
--cc=67536@debbugs.gnu.org \
/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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.