Avoid resizing mutation in subst-char-in-string

* lisp/subr.el (subst-char-in-string):
Use string-replace to avoid resizing mutation and O(n^2) time.
This commit is contained in:
Mattias Engdegård 2024-05-10 10:35:39 +02:00
parent 78761d699e
commit 184d6e8c02

View file

@ -5690,13 +5690,19 @@ The SEPARATOR regexp defaults to \"\\s-+\"."
(defun subst-char-in-string (fromchar tochar string &optional inplace)
"Replace FROMCHAR with TOCHAR in STRING each time it occurs.
Unless optional argument INPLACE is non-nil, return a new string."
(let ((i (length string))
(newstr (if inplace string (copy-sequence string))))
(while (> i 0)
(setq i (1- i))
(if (eq (aref newstr i) fromchar)
(aset newstr i tochar)))
newstr))
(if (and (not inplace)
(if (multibyte-string-p string)
(> (max fromchar tochar) 127)
(> tochar 255)))
;; Avoid quadratic behaviour from resizing replacement.
(string-replace (string fromchar) (string tochar) string)
(let ((i (length string))
(newstr (if inplace string (copy-sequence string))))
(while (> i 0)
(setq i (1- i))
(if (eq (aref newstr i) fromchar)
(aset newstr i tochar)))
newstr)))
(defun string-replace (from-string to-string in-string)
"Replace FROM-STRING with TO-STRING in IN-STRING each time it occurs."