From: Xah <xahlee@gmail.com>
To: help-gnu-emacs@gnu.org
Subject: Re: elisp optimization question
Date: Thu, 8 May 2008 17:36:18 -0700 (PDT) [thread overview]
Message-ID: <c7c13a5d-462e-474f-b022-b1764ccd329b@1g2000prg.googlegroups.com> (raw)
In-Reply-To: mailman.11345.1210283700.18990.help-gnu-emacs@gnu.org
On May 8, 11:03 am, brad clawsie <claw...@fastmail.fm> wrote:
> hi, i use the following function to translate unicode and other
> entities found on the web into ascii that i can view in emacs-w3m. i
> am concerned that each search and replace as done in my example is
> inefficient, is there a better way to do this? i.e., is there a better
> way to group search/replace pairs? thanks in advance!
>
> (defun w3m-filter-brad (url)
> (goto-char (point-min))
> (while (re-search-forward "»" nil t)
> (replace-match ">>"))
> (goto-char (point-min))
> (while (re-search-forward "’" nil t)
> (replace-match "'"))
...
> )
I had similar problem and also thought about the efficiency or
different implementation issues.
Here's a alternative implementation. The idea is that instead of
working on buffer, you grab them into a string, and do replacement on
the string, then put them back in buffer. I haven't tested whether it
is faster, but i think David Kastrup mentioned in the past that
working on string is slower.
(defun fold (f x li)
"Recursively apply (f x i), where i is the ith element in the list
li.\n
For example, (fold f x '(1 2)) returns (f (f x 1) 2)"
(let ((li2 li) (ele) (x2 x))
(while (setq ele (pop li2))
(setq x2 (funcall f x2 ele))
)
x2
)
)
(defun replace-string-pairs (str pairs)
"Replace the string str repeatedy by the list pairs.\n
Example: (replace-string-pairs \"yes or no\"
'( (\"yes\" \"no\") (\"no\" \"n\") ) )
⇒ \"n or n\""
(fold (lambda (x y) ""
(replace-regexp-in-string
(nth 0 y) (nth 1 y) x) ) str pairs) )
you might use replace-string instead of replace-regexp-in-string.
--------------------
Also, the following are 3 different implementations.
The first is same as yours except in works on region, by first narrow-
to-region. The second is avoided the narrow-to-region by grabing the
region as string and work on the string. Since i heard that working on
string is slower, and since i want to avoid narrow-to-region, i
thougth of using a temp buffer instead. That's the third solution,
which i believe to be the best.
However, at the time either the 2nd or the 3rd solution had a bug, so
i switched back to the first. I haven't had time to investigate what
was the problem.
(defun replace-string-pairs-region (start end mylist)
"Replace string pairs in region.
Example syntax:
(replace-string-pairs-region start end '((\"alpha\" \"α\") (\"beta\"
\"β\")))
The search string and replace string are all literal."
(save-restriction
(narrow-to-region start end)
(mapc
(lambda (arg)
(goto-char (point-min))
(while (search-forward (car arg) nil t) (replace-match (cadr
arg) t t) ))
mylist)))
(defun replace-string-pairs-region2 (start end mylist)
"Replace string pairs in region.
Same as replace-string-pairs-region but with different implementation.
This implementation does not use narrow-to-region or save-restriction.
Is cleaner in a sense."
(let (mystr)
(setq mystr (buffer-substring start end))
(mapc
(lambda (x) (setq mystr (replace-regexp-in-string (car x) (cadr
x) mystr)))
mylist)
(delete-region start end)
(insert mystr)
)
)
(defun replace-string-pairs-region3 (start end mylist)
"Replace string pairs in region.
Same as replace-string-pairs-region but with different
implementation."
(let (mystr tempbuff)
(setq mystr (buffer-substring start end))
(setq tempbuff (concat " " (random)))
(save-current-buffer
(set-buffer (get-buffer-create tempbuff))
(insert mystr)
(mapc
(lambda (arg)
(goto-char (point-min))
(while (search-forward (car arg) nil t) (replace-match (cadr
arg) t t) ))
mylist)
(kill-buffer tempbuff)
)
(delete-region start end)
(insert mystr)
)
)
Xah
xah@xahlee.org
∑ http://xahlee.org/
☄
next prev parent reply other threads:[~2008-05-09 0:36 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <mailman.11345.1210283700.18990.help-gnu-emacs@gnu.org>
2008-05-09 0:00 ` elisp optimization question harven
2008-05-09 1:45 ` Kevin Rodgers
[not found] ` <mailman.11354.1210297808.18990.help-gnu-emacs@gnu.org>
2008-05-09 9:59 ` Rupert Swarbrick
2008-05-09 21:43 ` harven
2008-05-09 0:36 ` Xah [this message]
2008-05-08 18:03 brad clawsie
2008-05-08 22:14 ` Lennart Borgman (gmail)
2008-05-09 1:42 ` Kevin Rodgers
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
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c7c13a5d-462e-474f-b022-b1764ccd329b@1g2000prg.googlegroups.com \
--to=xahlee@gmail.com \
--cc=help-gnu-emacs@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.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).