bug-gnu-emacs
[Top][All Lists]
Advanced

[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---





reply via email to

[Prev in Thread] Current Thread [Next in Thread]