[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master c80adde1d9: Speed up `butlast`
From: |
Mattias Engdegård |
Subject: |
master c80adde1d9: Speed up `butlast` |
Date: |
Tue, 19 Jul 2022 06:17:25 -0400 (EDT) |
branch: master
commit c80adde1d95b1da45039e6ec39fa7dd12aab2a33
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>
Speed up `butlast`
* lisp/subr.el (butlast): Don't duplicate the removed part.
* test/lisp/subr-tests.el (subr-tests--butlast-ref, subr-butlast):
Add test.
---
lisp/subr.el | 11 +++++++----
test/lisp/subr-tests.el | 17 +++++++++++++++++
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/lisp/subr.el b/lisp/subr.el
index ca4d52535a..ef6cc41f3b 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -707,11 +707,14 @@ If N is bigger than the length of LIST, return LIST."
(defun butlast (list &optional n)
"Return a copy of LIST with the last N elements removed.
-If N is omitted or nil, the last element is removed from the
-copy."
+If N is omitted or nil, return a copy of LIST without its last element.
+If N is zero or negative, return LIST."
(declare (side-effect-free t))
- (if (and n (<= n 0)) list
- (nbutlast (copy-sequence list) n)))
+ (unless n
+ (setq n 1))
+ (if (<= n 0)
+ list
+ (take (- (length list) n) list)))
(defun nbutlast (list &optional n)
"Modify LIST to remove the last N elements.
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index ced2bc5c4e..f5c1c40263 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -1090,5 +1090,22 @@ final or penultimate step during initialization."))
(should-not (plistp '(1 2 3)))
(should-not (plistp '(1 2 3 . 4))))
+(defun subr-tests--butlast-ref (list &optional n)
+ "Reference implementation of `butlast'."
+ (let ((m (or n 1))
+ (len (length list)))
+ (let ((r nil))
+ (while (and list (> len m))
+ (push (car list) r)
+ (setq list (cdr list))
+ (setq len (1- len)))
+ (nreverse r))))
+
+(ert-deftest subr-butlast ()
+ (dolist (l '(nil '(a) '(a b) '(a b c) '(a b c d)))
+ (dolist (n (cons nil (number-sequence -2 6)))
+ (should (equal (butlast l n)
+ (subr-tests--butlast-ref l n))))))
+
(provide 'subr-tests)
;;; subr-tests.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master c80adde1d9: Speed up `butlast`,
Mattias Engdegård <=