I was looking at the clojure.core function re-groups:
(defn re-groups [^java.util.regex.Matcher m]
(let [gc (. m (groupCount))]
(if (zero? gc)
(. m (group))
(loop [ret [] c 0]
(if (<= c gc)
(recur (conj ret (. m (group c))) (inc c))
ret)))))
And thought that it would be "better" to rewrite it as a multimethod:
(defmulti re-groups (fn [^java.util.regex.Matcher m] (.groupCount m)))
(defmethod re-groups 0 [m] (.group m))
(defmethod re-groups :default [m]
(let [idxs (range (inc (.groupCount m)))]
(reduce #(conj %1 (.group m %2)) [] idxs)))
Yet when comparing the times I was surpised to see the rewrite is 4 times slower:
clojure.core: "Elapsed time: 668.029589 msecs"
multi-method: "Elapsed time: 2632.672379 msecs"
Is this a natural result of multimethods or is there something else wrong here?
Clojure multimethods allow runtime polymorphic behavior based on arbitrary dispatch functions. This is very powerful for building ad-hoc hierarchies and abstractions, but you pay a performance hit for such flexibility. You may wish to re-implement your solution with a protocol. Only use multimethods when you need complete runtime type flexibility.
in general anything that does more will take more time. because multimethods offer a variety of ways to dispatch they will take longer than protocols you I have to answer your question "yes, when compared to protocols".
In practice start with protocols and go to multimethods when you have to (and it looks like you need them). you can't make the computer faster with code, but you can make it do less
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With