packages: Optimize ‘all-packages’.

On my laptop, wall-clock time for (all-packages) goes from 27s to 1s.

* gnu/packages.scm (all-packages): Use a hash table to remember visited
packages instead of calling ‘delete-duplicates’ on the final list.

Change-Id: I4aae804656b56ef2095993e91f0572a5891f419f
This commit is contained in:
Ludovic Courtès 2024-12-02 17:06:52 +01:00
parent 12d00767f0
commit 97e7e47d6f
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5

View file

@ -258,18 +258,26 @@ (define all-packages
(mlambda ()
"Return the list of all public packages, including replacements and hidden
packages, excluding superseded packages."
(delete-duplicates
;; Note: 'fold-packages' never traverses the same package twice but
;; replacements break that (they may or may not be visible to
;; 'fold-packages'), hence this hash table to track visited packages.
(define visited (make-hash-table))
(fold-packages (lambda (package result)
(if (hashq-ref visited package)
result
(begin
(hashq-set! visited package #t)
(match (package-replacement package)
((? package? replacement)
(hashq-set! visited replacement #t)
(cons* replacement package result))
(#f
(cons package result))))
(cons package result))))))
'()
;; Dismiss deprecated packages but keep hidden packages.
#:select? (negate package-superseded))
eq?)))
#:select? (negate package-superseded))))
(define %package-cache-file
;; Location of the package cache.