~ruther/guix-local

2dce88d5bbe7a65e101c0734d1c6db44ecc8c299 — Ludovic Courtès 8 years ago 358b10b
derivations: Avoid string-to-bytevector conversions.

On Guile 2.2.1, this yields a 5% speedup on:

  guix build libreoffice xmonad certbot -n --no-substitutes --no-build-hook

* guix/derivations.scm (derivation->string): Rename to...
(derivation->bytevector): ... this.  Use 'open-bytevector-output-port'
instead of 'call-with-output-string'.
(derivation-hash): Remove string-to-bytevector conversion before
'sha256' call.
(build-expression->derivation): Use 'add-data-to-store' and an
bytevector port instead of a string port for the expression.
1 files changed, 22 insertions(+), 19 deletions(-)

M guix/derivations.scm
M guix/derivations.scm => guix/derivations.scm +22 -19
@@ 566,12 566,14 @@ that form."
     (write-list env-vars write-env-var port)
     (display ")" port))))

(define derivation->string
(define derivation->bytevector
  (mlambda (drv)
    "Return the external representation of DRV as a string."
    "Return the external representation of DRV as a UTF-8-encoded string."
    (with-fluids ((%default-port-encoding "UTF-8"))
      (call-with-output-string
        (cut write-derivation drv <>)))))
      (call-with-values open-bytevector-output-port
        (lambda (port get-bytevector)
          (write-derivation drv port)
          (get-bytevector))))))

(define* (derivation->output-path drv #:optional (output "out"))
  "Return the store path of its output OUTPUT.  Raise a


@@ 670,8 672,7 @@ derivation at FILE."
         ;; XXX: At this point this remains faster than `port-sha256', because
         ;; the SHA256 port's `write' method gets called for every single
         ;; character.
         (sha256
          (string->utf8 (derivation->string drv))))))))
         (sha256 (derivation->bytevector drv)))))))

(define (store-path type hash name)               ; makeStorePath
  "Return the store path for NAME/HASH/TYPE."


@@ 872,8 873,8 @@ output should not be used."
                                      system builder args env-vars #f))
         (drv        (add-output-paths drv-masked)))

    (let* ((file (add-text-to-store store (string-append name ".drv")
                                    (derivation->string drv)
    (let* ((file (add-data-to-store store (string-append name ".drv")
                                    (derivation->bytevector drv)
                                    (map derivation-input-path inputs)))
           (drv* (set-field drv (derivation-file-name) file)))
      (hash-set! %derivation-cache file drv*)


@@ 1237,23 1238,25 @@ ALLOWED-REFERENCES, DISALLOWED-REFERENCES, LOCAL-BUILD?, and SUBSTITUTABLE?."
                      ;; Guile sets it, but remove it to avoid conflicts when
                      ;; building Guile-using packages.
                      (unsetenv "LD_LIBRARY_PATH")))
         (builder  (add-text-to-store store
         (builder  (add-data-to-store store
                                      (string-append name "-guile-builder")

                                      ;; Explicitly use UTF-8 for determinism,
                                      ;; and also because UTF-8 output is faster.
                                      (with-fluids ((%default-port-encoding
                                                     "UTF-8"))
                                        (call-with-output-string
                                         (lambda (port)
                                           (write prologue port)
                                           (write
                                            `(exit
                                              ,(match exp
                                                 ((_ ...)
                                                  (remove module-form? exp))
                                                 (_ `(,exp))))
                                            port))))
                                        (call-with-values
                                            open-bytevector-output-port
                                          (lambda (port get-bv)
                                            (write prologue port)
                                            (write
                                             `(exit
                                               ,(match exp
                                                  ((_ ...)
                                                   (remove module-form? exp))
                                                  (_ `(,exp))))
                                             port)
                                            (get-bv))))

                                      ;; The references don't really matter
                                      ;; since the builder is always used in