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

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

bug#7174: 23.2; `last' can be made faster by using `length'


From: IRIE Shinsuke
Subject: bug#7174: 23.2; `last' can be made faster by using `length'
Date: Fri, 08 Oct 2010 10:31:46 +0900
User-agent: Wanderlust/2.15.6 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (Goj$(D+W(B) APEL/10.7 Emacs/23.2 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO)

Recently I saw the implementation of `last' in subr.el and found that
it counts the number of list elements on its own:

(defun last (list &optional n)
  "Return the last link of LIST.  Its car is the last element.
If LIST is nil, return nil.
If N is non-nil, return the Nth-to-last link of LIST.
If N is bigger than the length of LIST, return LIST."
  (if n
      (let ((m 0) (p list))
        (while (consp p)
          (setq m (1+ m) p (cdr p)))
        (if (<= n 0) p
          (if (< n m) (nthcdr (- m n) list) list)))
    (while (consp (cdr list))
      (setq list (cdr list)))
    list))

So I modified the code to use `length' as follows, and confirmed
it becomes much faster:

(defun last (list &optional n)
  "Return the last link of LIST.  Its car is the last element.
If LIST is nil, return nil.
If N is non-nil, return the Nth-to-last link of LIST.
If N is bigger than the length of LIST, return LIST."
  (if n
      (and (> n 0)
           (let ((m (length list)))
             (if (< n m) (nthcdr (- m n) list) list)))
    (and list
         (nthcdr (1- (length list)) list))))

Furthermore, the code can be made much simpler (but slower than
the above, in particular cases) as:

(defun last (list &optional n)
  "Return the last link of LIST.  Its car is the last element.
If LIST is nil, return nil.
If N is non-nil, return the Nth-to-last link of LIST.
If N is bigger than the length of LIST, return LIST."
  (nthcdr (- (length list) (or n 1)) list))

Thanks.

IRIE Shinsuke





reply via email to

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