从Clojure的一个系列中获取一些物品,为什么subvec比take& drop慢?

时间:2014-12-13 14:09:54

标签: clojure

是否有一种从集合中取出某些物品的自觉方式?

我是这样做的:

(time (drop 30 (take 70 (range 10001))))
;> "Elapsed time: 0.049797 msecs"
;> (30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69)

(time (subvec (vec (range 10001)) 30 70))
;> "Elapsed time: 2.072258 msecs"
;> [30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69]

问题:

  1. 为什么subvec方法比take& amp;放弃方法?
  2. 这样做的惯用方法是什么?

2 个答案:

答案 0 :(得分:2)

  1. vec不是懒,所以你要创建一个10001项的整个数组,然后取一个子矢量,而drop / take / range是懒的,所以只提供项目你需要。你不能对最后一个(10001-70)项目做任何事情,所以它们没有被创造/使用,因此没有时间

  2. 您的第一个版本对于您正在做的事情来说已经过时了。

答案 1 :(得分:2)

您的比较没有以适当的方式进行。

单个time不足以比较两个代码块。您应该使用dotimes多次重复它们,以便执行时间的差异更可靠:

;; returns the time it took to repeat running the code 1000 times
(time (dotimes [i 1000] your-code-block))

在第二个代码块中,您将range返回的延迟序列转换为带vec的向量,这也需要一些额外的时间:

(vec (range 10001))

您可以使用time + dotimes技术将上述内容与(range 10001)本身进行比较。

我希望这将成为你进一步探索的基础。