Clojure查找性能向量与集合

Clojure查找性能向量与集合,clojure,Clojure,我有一个少于50个分类项目的小集合,我经常检查集合中是否有特定项目 这个, 如果我使用一套,需要10毫秒 (time (let [a (sorted-set 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)] (dotimes [i 100000] (a 15)))) 它总是至少需要两倍的时间。我不明白的是,set应该针对查找进行优化,为什么过滤器更快?过滤器是懒惰的。因为您没有计算(filter(fn[[k]](=k 15))a的结果)它实际上什么都不做

我有一个少于50个分类项目的小集合,我经常检查集合中是否有特定项目

这个,

如果我使用一套,需要10毫秒

(time
 (let [a (sorted-set 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)]
   (dotimes [i 100000]
   (a 15))))

它总是至少需要两倍的时间。我不明白的是,set应该针对查找进行优化,为什么过滤器更快?

过滤器是懒惰的。因为您没有计算
(filter(fn[[k]](=k 15))a的结果)
它实际上什么都不做,只是生成一个惰性序列

事实上,
(fn[[k]](=k 15))
甚至都不正确,但您看不到这一点,因为它没有经过计算

(let [a [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]]
     (filter (fn [[k]] (= k 15)) a))
=> java.lang.UnsupportedOperationException: nth not supported on this type: Integer
    [Thrown class java.lang.RuntimeException]
你想要什么

(time
 (let [a [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]]
   (dotimes [i 100000]
     (some (fn [k] (= k 15)) a))))

"Elapsed time: 173.689 msecs"
nil
而不是不正确的:

(time
 (let [a [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]]
   (dotimes [i 100000]
     (filter (fn [[k]] (= k 15)) a))))

"Elapsed time: 33.852 msecs"
nil

filter
是一个惰性函数。尝试先添加
first
,以强制计算
filter
函数生成的延迟序列。匿名函数中还有一个小错误:

(time
 (let [a [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]]
   (dotimes [i 100000]
     (first (filter (fn [k] (= k 15)) a)))))

"Elapsed time: 126.659769 msecs"
排序集:

(time
 (let [a (sorted-set 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)]
   (dotimes [i 100000]
   (a 15))))
"Elapsed time: 19.467465 msecs"
希望是有意义的

(time
 (let [a (sorted-set 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)]
   (dotimes [i 100000]
   (a 15))))
"Elapsed time: 19.467465 msecs"