ab7ad2d6f641

Optimize `find-anonymous-variables`

After some profiling I found that this function was taking 4% of the total
runtime just on its own.  The culprit was `tree-collect`, which does some
expensive things (like `(gensym)`).  Because we know exactly what we need we can
write something much faster, and profiling confirms that this function isn't
even on the map any more.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Mon, 11 Jul 2016 21:38:03 +0000
parents d2ede3f3926a
children 789aa5540746
branches/tags (none)
files package.lisp src/utils.lisp src/wam/compiler.lisp

Changes

--- a/package.lisp	Mon Jul 11 20:30:27 2016 +0000
+++ b/package.lisp	Mon Jul 11 21:38:03 2016 +0000
@@ -13,7 +13,6 @@
     #:recursively
     #:recur
     #:when-let
-    #:unique-items
     #:dis
     #:megabytes
     #:gethash-or-init
--- a/src/utils.lisp	Mon Jul 11 20:30:27 2016 +0000
+++ b/src/utils.lisp	Mon Jul 11 21:38:03 2016 +0000
@@ -42,19 +42,6 @@
   `(let ((,symbol ,value))
      (when ,symbol ,@body)))
 
-(defun unique-items (list)
-  "Return a list of the items that appear exactly once in `list`."
-  (loop
-    :with once = nil
-    :with seen = nil
-    :for item :in list
-    :do (if (member item seen)
-          (when (member item once)
-            (setf once (delete item once)))
-          (progn (push item seen)
-                 (push item once)))
-    :finally (return once)))
-
 (defmacro dis (arglist &body body)
   "Disassemble the code generated for a `lambda*` with `arglist` and `body`.
 
--- a/src/wam/compiler.lisp	Mon Jul 11 20:30:27 2016 +0000
+++ b/src/wam/compiler.lisp	Mon Jul 11 21:38:03 2016 +0000
@@ -364,7 +364,19 @@
   Anonymous variables are variables that are only ever used once.
 
   "
-  (unique-items (tree-collect #'variablep clause)))
+  (let ((seen nil)
+        (once nil))
+    (recursively ((term clause))
+      (cond
+        ((variablep term)
+         (if (member term seen)
+           (when (member term once)
+             (setf once (delete term once)))
+           (progn (push term seen)
+                  (push term once))))
+        ((consp term) (recur (car term))
+                      (recur (cdr term)))))
+    once))
 
 
 (defun* determine-clause-properties (head body)