diff options
author | Ludovic Courtès <ludo@gnu.org> | 2015-04-17 18:15:38 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2015-04-17 18:15:38 +0200 |
commit | 8d7dc5d9dbf009009d33e21598f92c4685965cd5 (patch) | |
tree | a5f6a3fe1ab6a4753ade4a6001c3d746dd7668b7 | |
parent | 5e25ebe2fa70297d094fe891b81c4970e45a906a (diff) | |
download | guix-8d7dc5d9dbf009009d33e21598f92c4685965cd5.tar.gz |
monads: Optimize 'sequence'.
* guix/monads.scm (sequence): Rewrite as a macro. This yields a 10% improvement in wall-clock time for 'guix system build'.
-rw-r--r-- | guix/monads.scm | 16 |
1 files changed, 14 insertions, 2 deletions
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, |