Clojure中多方法与cond的性能 [英] Performance of multimethod vs cond in Clojure

查看:35
本文介绍了Clojure中多方法与cond的性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

多方法比协议慢,即使使用多方法提供了一种更灵活的解决方案,也应在它们可以解决问题时尝试使用协议。
那么 cond 和multimethod怎么办?它们可以用来解决相同的问题,但我猜想,与 cond 相比,多方法具有巨大的性能开销。如果是这样,我为什么要使用多重方法而不是 cond

Multimethods are slower than protocols and one should try to use protocols when they can solve the problem, even though using multimethods gives a more flexible solution. So what is the case with cond and multimethod? They can be used to solve the same problem but my guess is that multimethod has a huge performance overhead vs cond. If so why would i ever want to use multimethod instead of cond?

推荐答案

<为了跟进@AlexMiller的评论,我尝试使用更多随机数据进行基准测试,并添加了协议实现(还为不同的方法添加了另一种类型-Integer)。

To follow up on @AlexMiller comment, I tried to benchmark with more randomised data and added up the protocol implementation (also added one more type - Integer - to the different methods).

(defprotocol StrConvert
  (to-str [this]))

(extend-protocol StrConvert
  nil
  (to-str [this] "null")
  java.lang.Integer
  (to-str [this] (str this))
  java.lang.String
  (to-str [this] (str "\"" this "\""))
  clojure.lang.Keyword
  (to-str [this] (to-str (name this)))
  java.lang.Object
  (to-str [this] (str this)))

data 包含10000个随机整数序列,这些整数随机转换为字符串 nil 关键字向量

data contains a sequence of 10000 random integers, that are randomly converted to String, nil, keyword or vector.

(let [fns [identity            ; as is (integer)
           str                 ; stringify
           (fn [_] nil)        ; nilify
           #(-> % str keyword) ; keywordize
           vector]             ; vectorize
      data (doall (map #(let [f (rand-nth fns)] (f %))
                       (repeatedly 10000 (partial rand-int 1000000))))]
  ;; print a summary of what we have in data
  (println (map (fn [[k v]] [k (count v)]) (group-by class data)))
  ;; multimethods
  (c/quick-bench (dorun (map convert data)))
  ;; cond-itionnal
  (c/quick-bench (dorun (map convert-cond data)))
  ;; protocols
  (c/quick-bench (dorun (map to-str data))))

结果是针对包含以下内容的数据

The result is for data containing :

([clojure.lang.PersistentVector 1999] [clojure.lang.Keyword 1949]
 [java.lang.Integer 2021] [java.lang.String 2069] [nil 1962])




  • 多种方法:6.26 ms

  • 条件:5.18 ms

  • 协议:6.04毫秒

  • 我当然会建议@DanielCompton:设计比纯粹的性能更重要至少在此示例中,每种方法似乎成对出现。

    I would certainly suggest as @DanielCompton : the design matters more than the pure performances that seem on pair for each method, at least on this example.

    这篇关于Clojure中多方法与cond的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆