我有个功能,福:
(defn foo [a b] (* a b)) ; <- 2 ms per 10K
(foo 3 8) ; <- 24
我也想把它传递给代理人、原子或参考文献。
(defn bar [a b] (* @a @b)) ; <- 3.5 ms per 10K
那么混合文字和代理又如何呢?
(defn aref? [x] (isa? (class x) clojure.lang.ARef))
(defn foo [a b] (let [a (if (aref? a) @a a)
b (if (aref? b) @b b)]
(* a b))
(def x (ref 3))
(def y (ref 8))
(foo 3 8); <- 120 ms per 10K
(foo 3 y); <- 71 ms per 10K
(foo x 8); <- 73 ms per 10K
(foo x y); <- 6 ms per 10K
但这是一些非常时髦的跑步时间。我试图在foo
中更改分支的顺序,这显然与此无关。为什么我的新foo
要比在ARefs上花费20倍的时间来评估文字呢?
发布于 2014-04-12 15:59:26
实际上,正如ez121sl提到的,性能差异来自于isa?
的使用。查看其源代码,您会发现它使用内置的global-hierarchy
(如果没有提供),并递归检查child
类的任何bases
(基类)是否是定义的parent
类。
使用instance?
(它在幕后使用instanceof?
)会在更明智的时候产生效果。
(defn aref? [x]
(instance? clojure.lang.ARef x))
(defn foo [a b] (let [a (if (aref? a) @a a)
b (if (aref? b) @b b)]
(* a b)))
(def a (ref 3))
(def b (ref 8))
(time (dotimes [i 10000] (foo a b))) ; ~ 9ms
(time (dotimes [i 10000] (foo a 8))) ; ~ 2.7ms
(time (dotimes [i 10000] (foo 3 b))) ; ~ 2.7ms
(time (dotimes [i 10000] (foo 3 8))) ; ~ 1.7ms
https://stackoverflow.com/questions/23031864
复制相似问题