[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#29866: 27.0.50; cl-loop: Calculate the array length just once
From: |
Tino Calancha |
Subject: |
bug#29866: 27.0.50; cl-loop: Calculate the array length just once |
Date: |
Thu, 28 Dec 2017 05:13:21 +0900 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) |
Tino Calancha <tino.calancha@gmail.com> writes:
> X-Debbugs-CC: monnier@iro.umontreal.ca
>
> It looks sensible to calculate the array length just once,
> instead of recalculate it on each iteration:
I have checked after my nap for more optimizations like that.
The patch below pass the tests.
As long as the length of the seq be an invariant (is it?), then
it must be OK to store it in `temp-seq'.
--8<-----------------------------cut here---------------start------------->8---
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index f671aea399..d70cf7d664 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -1338,6 +1338,7 @@ cl--parse-loop-clause
(error "Expected `of'"))))
(seq (cl--pop2 cl--loop-args))
(temp-seq (make-symbol "--cl-seq--"))
+ (temp-len (make-symbol "--cl-len--"))
(temp-idx
(if (eq (car cl--loop-args) 'using)
(if (and (= (length (cadr cl--loop-args)) 2)
@@ -1348,16 +1349,19 @@ cl--parse-loop-clause
(push (list temp-seq seq) loop-for-bindings)
(push (list temp-idx 0) loop-for-bindings)
(if ref
- (let ((temp-len (make-symbol "--cl-len--")))
+ (progn
(push (list temp-len `(length ,temp-seq))
loop-for-bindings)
(push (list var `(elt ,temp-seq ,temp-idx))
cl--loop-symbol-macs)
(push `(< ,temp-idx ,temp-len) cl--loop-body))
+ ;; Evaluate seq length just if needed, that is, when seq
is not a cons.
+ (push (list temp-len (or (consp seq) `(length ,temp-seq)))
+ loop-for-bindings)
(push (list var nil) loop-for-bindings)
(push `(and ,temp-seq
(or (consp ,temp-seq)
- (< ,temp-idx (length ,temp-seq))))
+ (< ,temp-idx ,temp-len)))
cl--loop-body)
(push (list var `(if (consp ,temp-seq)
(pop ,temp-seq)
--8<-----------------------------cut here---------------end--------------->8---