specter

itaied 2024-03-12T10:39:57.863509Z

Hi, a question regarding specter performance Im testing the following transformation function, and i face a big difference

(defn convert-sizes-sp
  [layout]
  (sp/multi-transform
   [(sp/multi-path
     [(sp/must :size) (sp/cond-path number? (sp/terminal #(str % "fr"))
                                    keyword? (sp/terminal #(size-alias %)))]
     [(sp/submap [:y :x :z]) sp/MAP-VALS sp/ALL (sp/terminal convert-sizes-sp)])]
   layout))

(defn convert-sizes-f
  [layout]
  (cond-> layout
    (:size layout) (update :size (fn [size] (cond (number? size) (str size "fr")
                                                  (keyword? size) (size-alias size)
                                                  :else size)))
    (:x layout) (update :x (partial mapv convert-sizes-f))
    (:y layout) (update :y (partial mapv convert-sizes-f))
    (:z layout) (update :z (partial mapv convert-sizes-f))))

(let [input {:x [{:size 1} {:size 1} {:y [{:size 1} {:size 2} {:size 3}]}], :y [{:size "5px"} {:size 10}]}]
  (println (timeit 1000 (convert-sizes-sp input))) ; 600 msec
  (println (timeit 1000 (convert-sizes-f input)))  ; 12 msec
)
what am i missing?
(defmacro timeit
          ([expr] `(timeit 1 ~expr))
          ([times expr] `(->> ~expr
                              (dotimes [_# ~times])
                              (time)
                              (with-out-str)
                              (re-find #"\d+\.\d+")
                              (js/Number))))

nathanmarz 2024-03-12T17:58:19.349279Z

is this Clojurescript?

itaied 2024-03-12T17:59:10.322149Z

yes

nathanmarz 2024-03-12T18:10:37.837749Z

specter's not as optimized for clojurescript as it is for clojure

nathanmarz 2024-03-12T18:10:49.971839Z

it's been awhile since I looked at it, but I recall there being some limitations with cljs

itaied 2024-03-12T18:18:23.232639Z

can you recall the limitations? are they specific on some functions?

nathanmarz 2024-03-12T19:12:47.086139Z

glancing at the code, it's definitely less efficient if the path has any dynamic references in it

nathanmarz 2024-03-12T19:13:40.450089Z

if you bind com.rpl.specter.impl/*DEBUG-INLINE-CACHING* to true before compiling the callsite, you'll get more info

itaied 2024-03-12T21:17:07.626449Z

ok ill give it a try, thanks

wcohen 2024-03-12T14:30:33.363519Z

It’s been a few years since I’ve last needed specter, but I just wanted to provide a reiterated thanks. A few mins of re-reading the docs today and I’ve been able to quickly navigate some messy trees that sit squarely in specter’s use case.

🚀 3