all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Paul Pogonyshev <pogonyshev@gmail.com>
To: Emacs developers <emacs-devel@gnu.org>
Subject: [patch] generator function optimizations
Date: Sun, 12 Mar 2017 11:59:44 +0100	[thread overview]
Message-ID: <CAG7BparaUdrZ0wAgn_AT2o0Vt1vSUf5NA1fbROfy=McgeqdNyw@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 851 bytes --]

Generator functions are translated into a set of closures
that work together. While documentation says that they are
"somewhat less efficient than conventional elisp routines",
that seems to be an understatement.

In my real code (a very large function used as a co-routine)
with 60 yields, generator function has over 1000 lambdas.
I see several ways to improve this at least somewhat.

The patch below improves transformation of `progn' forms.
Here it results in 30 lambdas in the generator function fewer.
Not great (~ -3%), but I guess in other cases it can give a
larger improvement.

All unit-tests pass.

If this patch is accepted, I can work on some other ideas
I have.

Paul


* lisp/emacs-lisp/generator.el (cps--transform-1): When
transforming `progn' form with several atomic forms at the
beginning, create only one state for all of them.

[-- Attachment #2: generators.diff --]
[-- Type: text/plain, Size: 2090 bytes --]

diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el
index 2ab01404ba..a3462971f8 100644
--- a/lisp/emacs-lisp/generator.el
+++ b/lisp/emacs-lisp/generator.el
@@ -286,19 +286,25 @@ don't yield.")
     ;; Process `progn' and `inline': they are identical except for the
     ;; name, which has some significance to the byte compiler.
 
-    (`(inline) (cps--transform-1 nil next-state))
-    (`(inline ,form) (cps--transform-1 form next-state))
-    (`(inline ,form . ,rest)
-      (cps--transform-1 form
-                        (cps--transform-1 `(inline ,@rest)
-                                          next-state)))
-
-    (`(progn) (cps--transform-1 nil next-state))
-    (`(progn ,form) (cps--transform-1 form next-state))
-    (`(progn ,form . ,rest)
-      (cps--transform-1 form
-                        (cps--transform-1 `(progn ,@rest)
-                                          next-state)))
+    (`(,(or 'inline 'progn)) (cps--transform-1 nil next-state))
+    (`(,(or 'inline 'progn) ,form) (cps--transform-1 form next-state))
+    (`(,(and (or 'inline 'progn) progn-type) ,form . ,rest)
+      (let (atomic-head)
+        ;; When there are several atomic (i.e. without `iter-yield')
+        ;; forms at the beginning, don't create a separate state for
+        ;; each of them, but rather one for all.
+        (unless cps-inhibit-atomic-optimization
+          (when (cps--atomic-p form)
+            (setf atomic-head (list form))
+            (while (and rest (cps--atomic-p (car rest)))
+              (push (pop rest) atomic-head))))
+        (if atomic-head
+            (cps--make-atomic-state `(,progn-type ,@(nreverse atomic-head))
+                                    (cps--transform-1 `(,progn-type ,@rest)
+                                                      next-state))
+          (cps--transform-1 form
+                            (cps--transform-1 `(,progn-type ,@rest)
+                                              next-state)))))
 
     ;; Process `let' in a helper function that transforms it into a
     ;; let* with temporaries.

             reply	other threads:[~2017-03-12 10:59 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-12 10:59 Paul Pogonyshev [this message]
2017-03-12 17:21 ` [patch] generator function optimizations Stefan Monnier
2017-03-12 22:26 ` Andreas Politz
2017-03-12 22:33   ` Noam Postavsky
2017-03-12 22:44     ` Andreas Politz
  -- strict thread matches above, loose matches on Subject: below --
2017-03-12 19:12 Paul Pogonyshev
2017-03-12 21:53 ` Stefan Monnier

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='CAG7BparaUdrZ0wAgn_AT2o0Vt1vSUf5NA1fbROfy=McgeqdNyw@mail.gmail.com' \
    --to=pogonyshev@gmail.com \
    --cc=emacs-devel@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.