sci icon indicating copy to clipboard operation
sci copied to clipboard

Optimize protocol/multi-method calls

Open borkdude opened this issue 3 years ago • 0 comments

Example:

$ cat /tmp/foo.clj
(defrecord Example []
  clojure.lang.IDeref
  (deref [this] :deref)

  clojure.lang.IAtom
  (reset [this new-value] :reset)

  (swap  [this f]          :swap)
  (swap  [this f a]        :swap)
  (swap  [this f a b]      :swap)
  (swap  [this f a b args] :swap)

  (compareAndSet [this oldv newv] true))

(time
 [@(->Example)
  (reset! (->Example) 1)
  (swap! (->Example) inc)
  (swap! (->Example) + 1)
  (swap! (->Example) + 1 2)
  (swap! (->Example) + 1 2 3)
  (compare-and-set! (->Example) 1 2)])

This is much slower in bb than on the JVM:

$ ~/Downloads/bb-ideref /tmp/foo.clj
"Elapsed time: 0.15758 msecs"
[:deref :reset :swap :swap :swap :swap true]
$ clj /tmp/foo.clj
"Elapsed time: 0.063916 msecs"

Apply is much slower than a regular fn-call, this might be one of the causes.

user=> (time (dotimes [i 1000000000] (foo 1 2)))
"Elapsed time: 2534.94129 msecs"
nil
user=> (time (dotimes [i 1000000000] (apply foo [1 2])))
"Elapsed time: 37887.344147 msecs"
nil

borkdude avatar Sep 14 '20 11:09 borkdude