From: "Mattias Engdegård" <mattiase@acm.org>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: 36139@debbugs.gnu.org
Subject: bug#36139: [PATCH] Make better use of the switch op in cond forms
Date: Wed, 19 Jun 2019 16:03:43 +0200 [thread overview]
Message-ID: <7A5D1F4E-5FA9-4F09-A4DA-97121DB4423E@acm.org> (raw)
In-Reply-To: <jwvk1di7m93.fsf-monnier+emacs@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 847 bytes --]
18 juni 2019 kl. 21.03 skrev Stefan Monnier <monnier@iro.umontreal.ca>:
>
> LGTM. The other direction is to just always use `member`
> and speed up the implementation of `member` by testing the type of
> the first arg and dispatch to memq/memql when possible.
Here is a patch that does some cheap static optimisations: equal/eql and member/memql become eq and memq if constant symbols are involved. (Works for me, bootstraps fine, etc.)
I considered doing the same for equal->eql and member->memql. It turns out that equal is faster than eql for numbers, since eql doesn't have its own byte op. For the same reason, member is faster than memql for lists of up to 5 elements (on this machine). While we could reduce equal to eql for constant lists > 5 elements of only symbols and numbers, it's perhaps more trouble than it's worth.
[-- Attachment #2: 0001-Strength-reduce-equal-eql-member-and-memql.patch --]
[-- Type: application/octet-stream, Size: 3179 bytes --]
From e5f3da7af6cc209d4b29378d41427937d8a32435 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= <mattiase@acm.org>
Date: Wed, 19 Jun 2019 13:26:58 +0200
Subject: [PATCH] Strength-reduce `equal', `eql', `member' and `memql'
When comparing against symbols, turn `equal' and `eql' into `eq',
and `member' and `memql' into `memq'.
* lisp/emacs-lisp/byte-opt.el (byte-optimizer--constant-symbol-p)
(byte-optimize-equal, byte-optimize-member): New.
(member, memql, equal, eql): Use new byte-optimizers.
---
lisp/emacs-lisp/byte-opt.el | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index b0aa407c8b..ca08b2ce50 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -834,6 +834,36 @@ byte-optimize-identity
(if (= 1 (length (cdr form))) "" "s"))
form))
+(defun byte-optimizer--constant-symbol-p (expr)
+ "Whether EXPR is a constant symbol."
+ (and (macroexp-const-p expr) (symbolp (eval expr))))
+
+(defun byte-optimize-equal (form)
+ ;; Replace `equal' or `eql' with `eq' if at least one arg is a symbol.
+ (if (= (length (cdr form)) 2)
+ (let ((form (byte-optimize-binary-predicate form)))
+ (if (or (byte-optimizer--constant-symbol-p (nth 1 form))
+ (byte-optimizer--constant-symbol-p (nth 2 form)))
+ (cons 'eq (cdr form))
+ form))
+ ;; Arity errors reported elsewhere.
+ form))
+
+(defun byte-optimize-member (form)
+ ;; Replace `member' or `memql' with `memq' if the first arg is a symbol,
+ ;; or the second arg is a list of symbols.
+ (if (= (length (cdr form)) 2)
+ (if (or (byte-optimizer--constant-symbol-p (nth 1 form))
+ (let ((arg2 (nth 2 form)))
+ (and (macroexp-const-p arg2)
+ (let ((listval (eval arg2)))
+ (and (listp listval)
+ (not (memq nil (mapcar #'symbolp listval))))))))
+ (cons 'memq (cdr form))
+ form)
+ ;; Arity errors reported elsewhere.
+ form))
+
(defun byte-optimize-memq (form)
;; (memq foo '(bar)) => (and (eq foo 'bar) '(bar))
(if (/= (length (cdr form)) 2)
@@ -852,6 +882,8 @@ byte-optimize-memq
(put 'identity 'byte-optimizer 'byte-optimize-identity)
(put 'memq 'byte-optimizer 'byte-optimize-memq)
+(put 'memql 'byte-optimizer 'byte-optimize-member)
+(put 'member 'byte-optimizer 'byte-optimize-member)
(put '+ 'byte-optimizer 'byte-optimize-plus)
(put '* 'byte-optimizer 'byte-optimize-multiply)
@@ -862,7 +894,8 @@ byte-optimize-memq
(put '= 'byte-optimizer 'byte-optimize-binary-predicate)
(put 'eq 'byte-optimizer 'byte-optimize-binary-predicate)
-(put 'equal 'byte-optimizer 'byte-optimize-binary-predicate)
+(put 'eql 'byte-optimizer 'byte-optimize-equal)
+(put 'equal 'byte-optimizer 'byte-optimize-equal)
(put 'string= 'byte-optimizer 'byte-optimize-binary-predicate)
(put 'string-equal 'byte-optimizer 'byte-optimize-binary-predicate)
--
2.20.1 (Apple Git-117)
next prev parent reply other threads:[~2019-06-19 14:03 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-08 14:40 bug#36139: [PATCH] Make better use of the switch op in cond forms Mattias Engdegård
2019-06-08 15:38 ` Drew Adams
2019-06-09 8:38 ` Mattias Engdegård
2019-06-10 15:38 ` npostavs
2019-06-11 11:12 ` Mattias Engdegård
2019-06-11 11:25 ` Noam Postavsky
2019-06-18 12:46 ` Mattias Engdegård
2019-06-18 18:48 ` Stefan Monnier
2019-06-19 9:25 ` Mattias Engdegård
2019-06-18 18:56 ` Stefan Monnier
2019-06-18 19:03 ` Stefan Monnier
2019-06-19 9:30 ` Mattias Engdegård
2019-06-19 14:03 ` Mattias Engdegård [this message]
2019-06-28 20:51 ` Mattias Engdegård
2019-06-18 19:06 ` Stefan Monnier
2019-06-19 9:30 ` Mattias Engdegård
2019-06-18 19:19 ` Stefan Monnier
2019-06-19 10:14 ` Mattias Engdegård
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=7A5D1F4E-5FA9-4F09-A4DA-97121DB4423E@acm.org \
--to=mattiase@acm.org \
--cc=36139@debbugs.gnu.org \
--cc=monnier@iro.umontreal.ca \
/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.