多方法比协议慢,应该尝试使用协议来解决问题,即使使用多方法提供了更灵活的解决方案.那么多方法是怎么回事cond?它们可以用来解决同样的问题,但我的猜测是多方法的性能开销很大cond.如果是这样,我为什么要使用多方法而不是cond?
多方法允许开放式扩展; 其他人可以在任意表达式上扩展你的多方法调度.Cond表达式被其他人甚至您自己的代码关闭以扩展.
如果你只是想对条件逻辑采取行动,那么cond就是你要走的路.如果您想要进行更复杂的调度,或者对具有不同行为的多种类型的数据应用函数,那么多方法可能更合适.
你可以测量时为什么担心?
这是使用标准库的基准样本.Cond和Multi-methods代码取自http://blog.8thlight.com/myles-megyesi/2012/04/26/polymorphism-in-clojure.html.
警告这只是进行基准比较multimethod和cond性能的一个示例.下面的结果 - 显示cond表现优于multimethod,不能推广到实践中的各种用法.您可以将此基准测试方法用于您自己的代码.
;; cond
(defn convert-cond [data]
(cond
(nil? data)
"null"
(string? data)
(str "\"" data "\"")
(keyword? data)
(convert-cond (name data))
:else
(str data)))
(bench (convert-cond "yolo"))
Evaluation count : 437830380 in 60 samples of 7297173 calls.
Execution time mean : 134.822430 ns
Execution time std-deviation : 1.134226 ns
Execution time lower quantile : 133.066750 ns ( 2.5%)
Execution time upper quantile : 137.077603 ns (97.5%)
Overhead used : 1.893383 ns
Found 2 outliers in 60 samples (3.3333 %)
low-severe 2 (3.3333 %)
Variance from outliers : 1.6389 % Variance is slightly inflated by outliers
;; multimethod
(defmulti convert class)
(defmethod convert clojure.lang.Keyword [data]
(convert (name data)))
(defmethod convert java.lang.String [data]
(str "\"" data "\""))
(defmethod convert nil [data]
"null")
(defmethod convert :default [data]
(str data))
(bench (convert "yolo"))
Evaluation count : 340091760 in 60 samples of 5668196 calls.
Execution time mean : 174.225558 ns
Execution time std-deviation : 1.824118 ns
Execution time lower quantile : 170.841203 ns ( 2.5%)
Execution time upper quantile : 177.465794 ns (97.5%)
Overhead used : 1.893383 ns
nil