【发布时间】:2011-08-31 17:12:34
【问题描述】:
我是looking atclojure.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)))))
并认为将其重写为多方法会“更好”:
(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)))
然而,当比较时间时,我惊讶地发现重写速度慢了 4 倍:
clojure.core: "Elapsed time: 668.029589 msecs"
multi-method: "Elapsed time: 2632.672379 msecs"
这是多方法的自然结果还是这里有其他问题?
【问题讨论】:
-
您似乎在这里使用多方法作为一种模式匹配结构。这真的不是多方法的目的,即(多)调度。把它想象成面向对象语言的超集。对于单次调度(如普通的 OO 东西)使用协议。对于模式匹配,请使用:github.com/swannodette/match
-
此外,clojure.core 代码正是出于性能原因而采用的方式,因此大多数其他实现会更慢。
标签: performance clojure multimethod