~ruther/guix-local

8d7dc5d9dbf009009d33e21598f92c4685965cd5 — Ludovic Courtès 11 years ago 5e25ebe
monads: Optimize 'sequence'.

* guix/monads.scm (sequence): Rewrite as a macro.  This yields a 10%
  improvement in wall-clock time for 'guix system build'.
1 files changed, 14 insertions(+), 2 deletions(-)

M guix/monads.scm
M guix/monads.scm => guix/monads.scm +14 -2
@@ 250,11 250,23 @@ to happen in that order."
                              lst)))
    (return (reverse result))))

(define-inlinable (sequence monad lst)
(define-syntax-rule (sequence monad lst)
  "Turn the list of monadic values LST into a monadic list of values, by
evaluating each item of LST in sequence."
  ;; XXX: Making it a macro is a bit brutal as it leads to a lot of code
  ;; duplication.  However, it allows >>= and return to be open-coded, which
  ;; avoids struct-ref's to MONAD and a few closure allocations when using
  ;; %STATE-MONAD.
  (with-monad monad
    (mapm monad return lst)))
    (let seq ((lstx   lst)
              (result '()))
      (match lstx
        (()
         (return (reverse result)))
        ((head . tail)
         (>>= head
              (lambda (item)
                (seq tail (cons item result)))))))))

(define (anym monad proc lst)
  "Apply PROC to the list of monadic values LST; return the first value,