Clojure ARefs上的奇异计算时间条件
我有一个函数foo:Clojure ARefs上的奇异计算时间条件,clojure,Clojure,我有一个函数foo: (defn foo [a b] (* a b)) ; <- 2 ms per 10K (foo 3 8) ; <- 24 (defn foo[ab](*ab)) 实际上,正如ez121sl所提到的,性能差异来自于使用isa?。查看其源代码,您会发现它使用内置的全局层次结构(如果没有提供),并递归检查子类的基类(基类)是否为定义的父类 使用instance?(在封面后面使用Java的instanceof?)会导致更合理的时间 (defn aref? [x]
(defn foo [a b] (* a b)) ; <- 2 ms per 10K
(foo 3 8) ; <- 24
(defn foo[ab](*ab)) 实际上,正如ez121sl所提到的,性能差异来自于使用isa?
。查看其源代码,您会发现它使用内置的全局层次结构(如果没有提供),并递归检查子类的基类(基类)是否为定义的父类
使用instance?
(在封面后面使用Java的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
我猜isa?的性能特征与Java的instanceof相似。当答案为false时,instanceof的性能更差。如果类不相同,则必须检查超类、实现的接口等。
(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
(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