mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-14 16:50:58 +00:00
Further seq-uniq speed-ups for lists
* lisp/emacs-lisp/seq.el (seq-uniq): Speed up more for long lists (bug#57079).
This commit is contained in:
parent
f947b20a19
commit
c0d761bf7f
@ -458,11 +458,21 @@ TESTFN is used to compare elements, or `equal' if TESTFN is nil."
|
||||
(cl-defmethod seq-uniq ((sequence list) &optional testfn)
|
||||
(let ((result nil))
|
||||
(if (not testfn)
|
||||
;; Fast path.
|
||||
(while sequence
|
||||
(unless (member (car sequence) result)
|
||||
(push (car sequence) result))
|
||||
(pop sequence))
|
||||
;; Fast path. If the list is long, use a hash table to speed
|
||||
;; things up even more.
|
||||
(let ((l (length sequence)))
|
||||
(if (> l 100)
|
||||
(let ((hash (make-hash-table :test #'equal :size l)))
|
||||
(while sequence
|
||||
(unless (gethash (car sequence) hash)
|
||||
(setf (gethash (car sequence) hash) t)
|
||||
(push (car sequence) result))
|
||||
(setq sequence (cdr sequence))))
|
||||
;; Short list.
|
||||
(while sequence
|
||||
(unless (member (car sequence) result)
|
||||
(push (car sequence) result))
|
||||
(pop sequence))))
|
||||
;; Slower path.
|
||||
(while sequence
|
||||
(unless (seq-find (lambda (elem)
|
||||
|
@ -570,7 +570,12 @@ Evaluate BODY for each created sequence.
|
||||
(substring "2")
|
||||
(substring "1"))))
|
||||
(should (equal (seq-uniq list) '("1" "2" "3")))
|
||||
(should (equal (seq-uniq list #'eq) '("1" "2" "3" "2" "1")))))
|
||||
(should (equal (seq-uniq list #'eq) '("1" "2" "3" "2" "1"))))
|
||||
;; Long lists have a different code path.
|
||||
(let ((list (seq-map-indexed (lambda (_ i) i)
|
||||
(make-list 10000 nil))))
|
||||
(should (= (length list) 10000))
|
||||
(should (= (length (seq-uniq (append list list))) 10000))))
|
||||
|
||||
(provide 'seq-tests)
|
||||
;;; seq-tests.el ends here
|
||||
|
Loading…
Reference in New Issue
Block a user