From b3c055cfb42f45ffe662f4fa24ce7b0104949eb2 Mon Sep 17 00:00:00 2001 From: Raffael Stocker Date: Fri, 1 Dec 2023 18:24:59 +0100 Subject: [PATCH] * lisp/calc/calc-aent.el (math-read-preprocess-string): cons less (bug#67536) Use a temp buffer instead of working on a string. This function is called by calc-eval, which in turn is called repeatedly when re-calculating org-mode tables. This function is one of the main bottlenecks there. --- lisp/calc/calc-aent.el | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lisp/calc/calc-aent.el b/lisp/calc/calc-aent.el index 66ede3295ae..84b580a7033 100644 --- a/lisp/calc/calc-aent.el +++ b/lisp/calc/calc-aent.el @@ -27,6 +27,7 @@ (require 'calc) (require 'calc-macs) +(eval-when-compile (require 'cl-lib)) ;; Declare functions which are defined elsewhere. (declare-function calc-digit-start-entry "calc" ()) @@ -550,19 +551,17 @@ math-read-subscripts ;;;###autoload (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 - (setq str - (replace-regexp-in-string (nth 0 (car rep-list)) - (nth 1 (car rep-list)) str)) - (setq rep-list (cdr rep-list)))) - str) + (with-temp-buffer + (cl-flet ((replace-all (regexp replacement) + (goto-char 0) + (while (re-search-forward regexp nil t) + (replace-match replacement)))) + (insert str) + (replace-all (concat "[" math-read-superscripts "]+") "^(\\&)") + (replace-all (concat "[" math-read-subscripts "]+") "_(\\&)") + (dolist (rep-elem math-read-replacement-list) + (replace-all (car rep-elem) (cadr rep-elem))) + (buffer-string)))) ;; The next few variables are local to math-read-exprs (and math-read-expr ;; in calc-ext.el), but are set in functions they call. -- 2.43.0