help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: elisp optimization question


From: Xah
Subject: Re: elisp optimization question
Date: Thu, 8 May 2008 17:36:18 -0700 (PDT)
User-agent: G2/1.0

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 "&#187;" nil t)
>     (replace-match "&gt;&gt;"))
>   (goto-char (point-min))
>   (while (re-search-forward "&#8217;" 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/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]