Welcome! Please see the About page for a little more info on how this works.

+1 vote
ago in Clojure by
edited ago by

I noticed that clojure.walk/walk is perhaps lazier internally than it necessarily needs to be. It uses several lazy (map) calls whose output then gets fully consumed.

Would it be considered to change these calls to either (mapv) or the transducer arity of (map) for performance considerations?

Here is a quick diff of a rough suggestion of changes:

diff --git a/src/clj/clojure/walk.clj b/src/clj/clojure/walk.clj
index 0f027e7a..96b089f6 100644
--- a/src/clj/clojure/walk.clj
+++ b/src/clj/clojure/walk.clj
@@ -41,13 +41,13 @@ the sorting function."}
   {:added "1.1"}
   [inner outer form]
   (cond
-   (list? form) (outer (with-meta (apply list (map inner form)) (meta form)))
+   (list? form) (outer (with-meta (apply list (mapv inner form)) (meta form)))
    (instance? clojure.lang.IMapEntry form)
    (outer (clojure.lang.MapEntry/create (inner (key form)) (inner (val form))))
-   (seq? form) (outer (with-meta (doall (map inner form)) (meta form)))
+   (seq? form) (outer (with-meta (seq (mapv inner form)) (meta form)))
    (instance? clojure.lang.IRecord form)
      (outer (reduce (fn [r x] (conj r (inner x))) form form))
-   (coll? form) (outer (into (empty form) (map inner form)))
+   (coll? form) (outer (into (empty form) (map inner) form))
    :else (outer form)))

 (defn postwalk
@@ -97,7 +97,7 @@ the sorting function."}
   [m]
   (let [f (fn [[k v]] (if (string? k) [(keyword k) v] [k v]))]
     ;; only apply to maps
-    (postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
+    (postwalk (fn [x] (if (map? x) (into {} (map f) x) x)) m)))

 (defn stringify-keys
   "Recursively transforms all map keys from keywords to strings."
@@ -105,7 +105,7 @@ the sorting function."}
   [m]
   (let [f (fn [[k v]] (if (keyword? k) [(name k) v] [k v]))]
     ;; only apply to maps
-    (postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
+    (postwalk (fn [x] (if (map? x) (into {} (map f) x) x)) m)))

Edit: this is somewhat related to some of the changes proposed in 0003-CLJ-1239-protocol-dispatch-for-clojure.walk.patch on CLJ-1239

Please log in or register to answer this question.

...