From: Tino Calancha <tino.calancha@gmail.com>
To: 25826@debbugs.gnu.org
Cc: tino.calancha@gmail.com
Subject: bug#25826: 26.0.50; cl-mapc and cl-mapl do needless consing
Date: Tue, 21 Feb 2017 17:04:54 +0900 [thread overview]
Message-ID: <87d1ecyno9.fsf@calancha-pc> (raw)
Current implementation of cl-mapc (cl-mapl) uses `cl-mapcar'
(`cl-maplist') when input contains > 1 sequence. Thus,
they cons the values and just discard then at the end.
Following patch adds a defvar which acts as a flag for consing
the values. The flag is bind to nil in the case of `cl-mapc' and
`cl-mapl'.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From 4ec295868fde6995e9044ee17b4a16829a1aa573 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Tue, 21 Feb 2017 12:21:13 +0900
Subject: [PATCH] Prevent for consing in cl-mapc and cl-mapl
* lisp/emacs-lisp/cl-extra.el (cl--accumulate): New defvar.
(cl--mapcar-many, cl-maplist): Accumulate values only if
cl--accumulate is non-nil (Bug#25826).
(cl-mapc, cl-mapl): Bind cl--accumulate to nil.
* lisp/emacs-lisp/cl-lib.el (mapcar): Add autoload cookie.
Accumulate values only if cl--accumulate is non-nil.
---
| 38 +++++++++++++++++++++++++-------------
lisp/emacs-lisp/cl-lib.el | 7 +++++--
2 files changed, 30 insertions(+), 15 deletions(-)
--git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index edd14b816f..60a454b897 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -88,6 +88,9 @@ cl-equalp
;;; Control structures.
+;; Bound to nil in `cl-mapc' and `cl-map-l'.
+(defvar cl--accumulate t)
+
;;;###autoload
(defun cl--mapcar-many (cl-func cl-seqs)
(if (cdr (cdr cl-seqs))
@@ -106,20 +109,23 @@ cl--mapcar-many
(setcar cl-p1 (cdr (car cl-p1))))
(aref (car cl-p1) cl-i)))
(setq cl-p1 (cdr cl-p1) cl-p2 (cdr cl-p2)))
- (push (apply cl-func cl-args) cl-res)
+ (if cl--accumulate
+ (push (apply cl-func cl-args) cl-res)
+ (apply cl-func cl-args))
(setq cl-i (1+ cl-i)))
- (nreverse cl-res))
+ (and cl--accumulate (nreverse cl-res)))
(let ((cl-res nil)
(cl-x (car cl-seqs))
(cl-y (nth 1 cl-seqs)))
(let ((cl-n (min (length cl-x) (length cl-y)))
(cl-i -1))
(while (< (setq cl-i (1+ cl-i)) cl-n)
- (push (funcall cl-func
+ (let ((val (funcall cl-func
(if (consp cl-x) (pop cl-x) (aref cl-x cl-i))
- (if (consp cl-y) (pop cl-y) (aref cl-y cl-i)))
- cl-res)))
- (nreverse cl-res))))
+ (if (consp cl-y) (pop cl-y) (aref cl-y cl-i)))))
+ (when cl--accumulate
+ (push val cl-res)))))
+ (and cl--accumulate (nreverse cl-res)))))
;;;###autoload
(defun cl-map (cl-type cl-func cl-seq &rest cl-rest)
@@ -140,23 +146,28 @@ cl-maplist
(cl-args (cons cl-list (copy-sequence cl-rest)))
cl-p)
(while (not (memq nil cl-args))
- (push (apply cl-func cl-args) cl-res)
+ (if cl--accumulate
+ (push (apply cl-func cl-args) cl-res)
+ (apply cl-func cl-args))
(setq cl-p cl-args)
(while cl-p (setcar cl-p (cdr (pop cl-p)) )))
- (nreverse cl-res))
+ (and cl--accumulate (nreverse cl-res)))
(let ((cl-res nil))
(while cl-list
- (push (funcall cl-func cl-list) cl-res)
+ (if cl--accumulate
+ (push (funcall cl-func cl-list) cl-res)
+ (funcall cl-func cl-list))
(setq cl-list (cdr cl-list)))
- (nreverse cl-res))))
+ (and cl--accumulate (nreverse cl-res)))))
;;;###autoload
(defun cl-mapc (cl-func cl-seq &rest cl-rest)
"Like `cl-mapcar', but does not accumulate values returned by the function.
\n(fn FUNCTION SEQUENCE...)"
(if cl-rest
- (progn (apply 'cl-map nil cl-func cl-seq cl-rest)
- cl-seq)
+ (let (cl--accumulate)
+ (apply 'cl-map nil cl-func cl-seq cl-rest)
+ cl-seq)
(mapc cl-func cl-seq)))
;;;###autoload
@@ -164,7 +175,8 @@ cl-mapl
"Like `cl-maplist', but does not accumulate values returned by the function.
\n(fn FUNCTION LIST...)"
(if cl-rest
- (apply 'cl-maplist cl-func cl-list cl-rest)
+ (let (cl--accumulate)
+ (apply 'cl-maplist cl-func cl-list cl-rest))
(let ((cl-p cl-list))
(while cl-p (funcall cl-func cl-p) (setq cl-p (cdr cl-p)))))
cl-list)
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el
index 5aa8f1bf65..b2d6d1cb1f 100644
--- a/lisp/emacs-lisp/cl-lib.el
+++ b/lisp/emacs-lisp/cl-lib.el
@@ -349,6 +349,7 @@ cl-float-negative-epsilon
(declare-function cl--mapcar-many "cl-extra" (cl-func cl-seqs))
+;;;###autoload
(defun cl-mapcar (cl-func cl-x &rest cl-rest)
"Apply FUNCTION to each element of SEQ, and make a list of the results.
If there are several SEQs, FUNCTION is called with that many arguments,
@@ -361,8 +362,10 @@ cl-mapcar
(cl--mapcar-many cl-func (cons cl-x cl-rest))
(let ((cl-res nil) (cl-y (car cl-rest)))
(while (and cl-x cl-y)
- (push (funcall cl-func (pop cl-x) (pop cl-y)) cl-res))
- (nreverse cl-res)))
+ (if cl--accumulate
+ (push (funcall cl-func (pop cl-x) (pop cl-y)) cl-res)
+ (funcall cl-func (pop cl-x) (pop cl-y))))
+ (and cl--accumulate (nreverse cl-res))))
(mapcar cl-func cl-x)))
(cl--defalias 'cl-svref 'aref)
--
2.11.0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.7)
of 2017-02-21
Repository revision: 96cea19842b577eb4f2e057d702aea54d736233e
next reply other threads:[~2017-02-21 8:04 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-21 8:04 Tino Calancha [this message]
2017-02-21 13:40 ` bug#25826: 26.0.50; cl-mapc and cl-mapl do needless consing npostavs
2017-02-22 3:08 ` Tino Calancha
2017-02-22 3:33 ` npostavs
2017-02-22 4:14 ` Tino Calancha
2017-02-22 5:46 ` Tino Calancha
2017-02-23 1:55 ` npostavs
2017-02-23 2:09 ` Tino Calancha
2017-02-27 7:36 ` Tino Calancha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87d1ecyno9.fsf@calancha-pc \
--to=tino.calancha@gmail.com \
--cc=25826@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.