mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2025-01-23 11:09:41 -05:00
derivations: Make 'coalesce-duplicate-inputs' linear in the number of inputs.
Partly fixes <https://issues.guix.gnu.org/49439>. Reported by Ricardo Wurmus <rekado@elephly.net>. When running the command: guix environment pigx-scrnaseq --search-paths --no-grafts this change reduces total heap allocations from 1.4GiB to 717MiB (49%) and wall-clock time from 7.5s to 5.7s (24%). Without '--no-grafts', heap allocations go from 2.1GiB to 1.4GiB (33%) and wall-clock time from 12.1s to 10.9s (10%). * guix/derivations.scm (coalesce-duplicate-inputs): Rewrite using a hash table to make it O(N) rather than O(N²).
This commit is contained in:
parent
5dc4fe1004
commit
78daf9e02e
1 changed files with 22 additions and 25 deletions
|
@ -241,32 +241,29 @@ (define (coalesce-duplicate-inputs inputs)
|
|||
"Return a list of inputs, such that when INPUTS contains the same DRV twice,
|
||||
they are coalesced, with their sub-derivations merged. This is needed because
|
||||
Nix itself keeps only one of them."
|
||||
(define (find pred lst) ;inlinable copy of 'find'
|
||||
(let loop ((lst lst))
|
||||
(match lst
|
||||
(() #f)
|
||||
((head . tail)
|
||||
(if (pred head) head (loop tail))))))
|
||||
(define table
|
||||
(make-hash-table 25))
|
||||
|
||||
(fold (lambda (input result)
|
||||
(match input
|
||||
(($ <derivation-input> (= derivation-file-name path) sub-drvs)
|
||||
;; XXX: quadratic
|
||||
(match (find (match-lambda
|
||||
(($ <derivation-input> (= derivation-file-name p)
|
||||
s)
|
||||
(string=? p path)))
|
||||
result)
|
||||
(#f
|
||||
(cons input result))
|
||||
((and dup ($ <derivation-input> drv sub-drvs2))
|
||||
;; Merge DUP with INPUT.
|
||||
(let ((sub-drvs (delete-duplicates
|
||||
(append sub-drvs sub-drvs2))))
|
||||
(cons (make-derivation-input drv (sort sub-drvs string<?))
|
||||
(delq dup result))))))))
|
||||
'()
|
||||
inputs))
|
||||
(for-each (lambda (input)
|
||||
(let* ((drv (derivation-input-path input))
|
||||
(sub-drvs (derivation-input-sub-derivations input)))
|
||||
(match (hash-get-handle table drv)
|
||||
(#f
|
||||
(hash-set! table drv input))
|
||||
((and handle (key . ($ <derivation-input> drv sub-drvs2)))
|
||||
;; Merge DUP with INPUT.
|
||||
(let* ((sub-drvs (delete-duplicates
|
||||
(append sub-drvs sub-drvs2)))
|
||||
(input
|
||||
(make-derivation-input drv
|
||||
(sort sub-drvs string<?))))
|
||||
(set-cdr! handle input))))))
|
||||
inputs)
|
||||
|
||||
(hash-fold (lambda (key input lst)
|
||||
(cons input lst))
|
||||
'()
|
||||
table))
|
||||
|
||||
(define* (derivation-prerequisites drv #:optional (cut? (const #f)))
|
||||
"Return the list of derivation-inputs required to build DRV, recursively.
|
||||
|
|
Loading…
Reference in a new issue