M S*_*ith 7 performance clojure multimethod
我在看 clojure.core函数重组:
(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)))))
Run Code Online (Sandbox Code Playgroud)
并认为将其重写为多方法会"更好":
(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)))
Run Code Online (Sandbox Code Playgroud)
然而,当比较我被惊讶的时候看到重写慢4倍:
clojure.core: "Elapsed time: 668.029589 msecs"
multi-method: "Elapsed time: 2632.672379 msecs"
Run Code Online (Sandbox Code Playgroud)
这是多方法的自然结果还是存在其他问题?
Clojure 多方法允许基于任意调度函数的运行时多态行为。这对于构建临时层次结构和抽象非常强大,但您会因为这种灵活性而付出性能损失。您可能希望使用协议重新实现您的解决方案。仅当您需要完整的运行时类型灵活性时才使用多方法。