From 8d7dc5d9dbf009009d33e21598f92c4685965cd5 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 17 Apr 2015 18:15:38 +0200 Subject: monads: Optimize 'sequence'. * guix/monads.scm (sequence): Rewrite as a macro. This yields a 10% improvement in wall-clock time for 'guix system build'. --- guix/monads.scm | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'guix') diff --git a/guix/monads.scm b/guix/monads.scm index 5bb860aadd..f693e99a59 100644 --- a/guix/monads.scm +++ b/guix/monads.scm @@ -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, -- cgit v1.2.3