diff options
author | Ludovic Courtès <ludo@gnu.org> | 2024-12-02 17:06:52 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2024-12-12 23:23:33 +0100 |
commit | 97e7e47d6f1e036e1ed6bd3f428e40d9794a3353 (patch) | |
tree | a2816fc59f1f4d9f2e570067414aa5073ac942e6 /gnu | |
parent | 12d00767f036029f1f5738de644d4972db374f4f (diff) | |
download | guix-97e7e47d6f1e036e1ed6bd3f428e40d9794a3353.tar.gz guix-97e7e47d6f1e036e1ed6bd3f428e40d9794a3353.zip |
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
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/packages.scm | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/gnu/packages.scm b/gnu/packages.scm index 1af3b8d440..bdd5d21940 100644 --- a/gnu/packages.scm +++ b/gnu/packages.scm @@ -258,18 +258,26 @@ is guaranteed to never traverse the same package twice." (mlambda () "Return the list of all public packages, including replacements and hidden packages, excluding superseded packages." - (delete-duplicates - (fold-packages (lambda (package result) - (match (package-replacement package) - ((? package? replacement) - (cons* replacement package result)) - (#f - (cons package result)))) - '() - - ;; Dismiss deprecated packages but keep hidden packages. - #:select? (negate package-superseded)) - eq?))) + ;; 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)))))) + '() + + ;; Dismiss deprecated packages but keep hidden packages. + #:select? (negate package-superseded)))) (define %package-cache-file ;; Location of the package cache. |