emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 44eca25: map.el (map-merge*): Use `map-into' at beg


From: Stefan Monnier
Subject: [Emacs-diffs] master 44eca25: map.el (map-merge*): Use `map-into' at beginning rather than end
Date: Sat, 18 Jun 2016 04:51:29 +0000 (UTC)

branch: master
commit 44eca25a4bd1513f08ca380c9f6722c21376ac9f
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    map.el (map-merge*): Use `map-into' at beginning rather than end
    
    * lisp/emacs-lisp/map.el (map-merge): Use `map-into' for the first map,
    and don't use of an intermediate alist.
    (map-merge-with): Same, plus use `cl-callf' to try and avoid performing
    3 lookups per inner iteration.
---
 lisp/emacs-lisp/map.el |   29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index ba15a65..b97d8b1 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -43,6 +43,7 @@
 ;;; Code:
 
 (require 'seq)
+(eval-when-compile (require 'cl-lib))
 
 (pcase-defmacro map (&rest args)
   "Build a `pcase' pattern matching map elements.
@@ -282,27 +283,33 @@ MAP can be a list, hash-table or array."
   "Merge into a map of type TYPE all the key/value pairs in MAPS.
 
 MAP can be a list, hash-table or array."
-  (let (result)
+  (let ((result (map-into (pop maps) type)))
     (while maps
+      ;; FIXME: When `type' is `list', we get an O(N^2) behavior.
+      ;; For small tables, this is fine, but for large tables, we
+      ;; should probably use a hash-table internally which we convert
+      ;; to an alist in the end.
       (map-apply (lambda (key value)
-                (setf (map-elt result key) value))
-              (pop maps)))
-    (map-into result type)))
+                   (setf (map-elt result key) value))
+                 (pop maps)))
+    result))
 
 (defun map-merge-with (type function &rest maps)
   "Merge into a map of type TYPE all the key/value pairs in MAPS.
 When two maps contain the same key, call FUNCTION on the two
 values and use the value returned by it.
 MAP can be a list, hash-table or array."
-  (let (result)
+  (let ((result (map-into (pop maps) type))
+        (not-found (cons nil nil)))
     (while maps
       (map-apply (lambda (key value)
-                (setf (map-elt result key)
-                      (if (map-contains-key result key)
-                          (funcall function (map-elt result key) value)
-                        value)))
-              (pop maps)))
-    (map-into result type)))
+                   (cl-callf (lambda (old)
+                               (if (eq old not-found)
+                                   value
+                                 (funcall function old value)))
+                       (map-elt result key not-found)))
+                 (pop maps)))
+    result))
 
 (defun map-into (map type)
   "Convert the map MAP into a map of type TYPE.



reply via email to

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