summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
authorMattias Engdegård <mattiase@acm.org>2020-07-25 19:12:26 +0200
committerMattias Engdegård <mattiase@acm.org>2020-07-25 19:24:56 +0200
commit609cbd63c31a21ca521507695abeda1203134c99 (patch)
tree52bd1f110dc18f2c8b85e845b99b8eb612d88978 /lisp/emacs-lisp
parent3b44829823f43d3736b8ec9db2258eeff7f6c16a (diff)
downloademacs-609cbd63c31a21ca521507695abeda1203134c99.tar.gz
emacs-609cbd63c31a21ca521507695abeda1203134c99.tar.bz2
emacs-609cbd63c31a21ca521507695abeda1203134c99.zip
Optimise 3-arg +, - and *
Turn (+ a b c) into (+ (+ a b) c), and do the same for - and *. The 2-arg operations have their own bytecode which results in a 1.5× speed-up. Furthermore, the transform enables other optimisations; for example, (+ a 1 b) -> (+ (1+ a) b). * lisp/emacs-lisp/byte-opt.el (byte-optimize-plus, byte-optimize-minus) (byte-optimize-multiply): Transform (OP a b c) into (OP (OP a b) c).
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/byte-opt.el10
1 files changed, 10 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 194ceee176f..6f801be5457 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -709,6 +709,9 @@
(integer (if integer-is-first arg1 arg2))
(other (if integer-is-first arg2 arg1)))
(list (if (eq integer 1) '1+ '1-) other)))
+ ;; (+ x y z) -> (+ (+ x y) z)
+ ((= (length args) 3)
+ `(+ ,(byte-optimize-plus `(+ ,(car args) ,(cadr args))) ,@(cddr args)))
;; not further optimized
((equal args (cdr form)) form)
(t (cons '+ args)))))
@@ -737,6 +740,9 @@
((and (null (cdr args))
(numberp (car args)))
(- (car args)))
+ ;; (- x y z) -> (- (- x y) z)
+ ((= (length args) 3)
+ `(- ,(byte-optimize-minus `(- ,(car args) ,(cadr args))) ,@(cddr args)))
;; not further optimized
((equal args (cdr form)) form)
(t (cons '- args))))))
@@ -764,6 +770,10 @@
((null args) 1)
;; (* n) -> n, where n is a number
((and (null (cdr args)) (numberp (car args))) (car args))
+ ;; (* x y z) -> (* (* x y) z)
+ ((= (length args) 3)
+ `(* ,(byte-optimize-multiply `(* ,(car args) ,(cadr args)))
+ ,@(cddr args)))
;; not further optimized
((equal args (cdr form)) form)
(t (cons '* args)))))