[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
01/01: monads: Optimize 'sequence'.
From: |
Ludovic Courtès |
Subject: |
01/01: monads: Optimize 'sequence'. |
Date: |
Fri, 17 Apr 2015 20:25:29 +0000 |
civodul pushed a commit to branch master
in repository guix.
commit 8d7dc5d9dbf009009d33e21598f92c4685965cd5
Author: Ludovic Courtès <address@hidden>
Date: Fri Apr 17 18:15:38 2015 +0200
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 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/guix/monads.scm b/guix/monads.scm
index 5bb860a..f693e99 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,