diff options
| author | Paul Eggert | 2018-08-20 15:52:29 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-08-20 16:01:31 -0700 |
| commit | eb83344fc7c08ec08b51e7700f1ac2632afa462c (patch) | |
| tree | 69c96f89acf42957ed98dc7ce189cb49d04abecd /test/src | |
| parent | 36de7bd7b0b9fcd038c440b4705e9186bfbaaa41 (diff) | |
| download | emacs-eb83344fc7c08ec08b51e7700f1ac2632afa462c.tar.gz emacs-eb83344fc7c08ec08b51e7700f1ac2632afa462c.zip | |
Speed up (nthcdr N L) when L is circular
Also, fix bug when N is a positive bignum, a problem reported
by Eli Zaretskii and Pip Cet in:
https://lists.gnu.org/r/emacs-devel/2018-08/msg00690.html
* src/fns.c (Fnthcdr): If a cycle is found, reduce the count
modulo the cycle length before continuing. This reduces the
worst-case cost of (nthcdr N L) from N to min(N, C) where C is
the number of distinct cdrs of L. Reducing modulo the cycle
length also allows us to do arithmetic with machine words
instead of with GMP.
* test/src/fns-tests.el (test-nthcdr-circular): New test.
Diffstat (limited to 'test/src')
| -rw-r--r-- | test/src/fns-tests.el | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index f722ed6333e..92dc18fa034 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el | |||
| @@ -624,4 +624,20 @@ | |||
| 624 | (should (eq (gethash b2 hash) | 624 | (should (eq (gethash b2 hash) |
| 625 | (funcall test b1 b2))))))) | 625 | (funcall test b1 b2))))))) |
| 626 | 626 | ||
| 627 | (ert-deftest test-nthcdr-circular () | ||
| 628 | (dolist (len '(1 2 5 37 120 997 1024)) | ||
| 629 | (let ((cycle (make-list len nil))) | ||
| 630 | (setcdr (last cycle) cycle) | ||
| 631 | (dolist (n (list (1- most-negative-fixnum) most-negative-fixnum | ||
| 632 | -1 0 1 | ||
| 633 | (1- len) len (1+ len) | ||
| 634 | most-positive-fixnum (1+ most-positive-fixnum) | ||
| 635 | (* 2 most-positive-fixnum) | ||
| 636 | (* most-positive-fixnum most-positive-fixnum) | ||
| 637 | (ash 1 12345))) | ||
| 638 | (let ((a (nthcdr n cycle)) | ||
| 639 | (b (if (<= n 0) cycle (nthcdr (mod n len) cycle)))) | ||
| 640 | (should (equal (list (eq a b) n len) | ||
| 641 | (list t n len)))))))) | ||
| 642 | |||
| 627 | (provide 'fns-tests) | 643 | (provide 'fns-tests) |