packages: Optimize 'find-packages-by-name' to avoid disk accesses.

On a profile with 182 entries, "guix package --search-paths" goes from
4.5 seconds down to 0.4 second.

* gnu/packages.scm (find-packages-by-name): Make a name -> package vhash
  in a promise; access it with 'vhash-fold*'.
This commit is contained in:
Ludovic Courtès 2014-09-29 21:39:39 +02:00
parent 34942e9597
commit 9ffc1c00e5
1 changed files with 13 additions and 15 deletions

View File

@ -179,22 +179,20 @@ same package twice."
vlist-null vlist-null
(all-package-modules)))) (all-package-modules))))
(define* (find-packages-by-name name #:optional version) (define find-packages-by-name
(let ((packages (delay
(fold-packages (lambda (p r)
(vhash-cons (package-name p) p r))
vlist-null))))
(lambda* (name #:optional version)
"Return the list of packages with the given NAME. If VERSION is not #f, "Return the list of packages with the given NAME. If VERSION is not #f,
then only return packages whose version is equal to VERSION." then only return packages whose version is equal to VERSION."
(define right-package? (let ((matching (vhash-fold* cons '() name (force packages))))
(if version (if version
(lambda (p) (filter (lambda (package)
(and (string=? (package-name p) name) (string=? (package-version package) version))
(string=? (package-version p) version))) matching)
(lambda (p) matching)))))
(string=? (package-name p) name))))
(fold-packages (lambda (package result)
(if (right-package? package)
(cons package result)
result))
'()))
(define find-newest-available-packages (define find-newest-available-packages
(memoize (memoize