在Clojure中,列表或向量访问两个最近的条目是否更快?

在Clojure中,列表或向量访问两个最近的条目是否更快?,clojure,Clojure,这是一种后续行动 假设我们需要访问集合中最近插入的两个元素。对于该操作,列表或向量会更快吗 这些是最快的选择吗 ; for list (def l '(3 2 1)) (peek l) => 3 (peek (pop l)) => 2 ; for vector (def v [1 2 3]) (peek v) => 3 (peek (pop v)) => 2 或者做以下事情会更快: (v (- (count v) 1)) => 3 (v (- (count v)

这是一种后续行动

假设我们需要访问集合中最近插入的两个元素。对于该操作,列表或向量会更快吗

这些是最快的选择吗

; for list
(def l '(3 2 1))
(peek l)
=> 3
(peek (pop l))
=> 2

; for vector
(def v [1 2 3])
(peek v)
=> 3
(peek (pop v))
=> 2
或者做以下事情会更快:

(v (- (count v) 1))
=> 3
(v (- (count v) 2))
=> 2
如果能解释一下如何正确分析这种情况,我将不胜感激。这是我的第一个游戏和Clojure程序,这就是我关心性能的原因。:)我不将这两个值打包在一起的原因是为了避免解包/映射它们,因为整个集合也有用途


谢谢大家!

如果我必须使用列表或向量,我会使用向量,因为
subvec
非常快

(let [a (vec (take 100000 (range)))]
    (time (subvec a (- (count a) 2))))
"Elapsed time: 0.045805 msecs"
=> [99998 99999]

但不清楚你想做什么。也许有更好的数据结构适合您的情况。

Clojure的向量使用了树外尾部优化,这基本上意味着,在填充之前,结构中的最新节点位于对象标头中,而不是放在树中。因此,您应该看到在
n
元素树中,对
n%32
索引最高的元素进行恒定时间查找


对于最严格意义上的列表,到达第二个元素将始终涉及沿着元素1的链(两个步骤),但是如果您确实对
seq
进行了隐式调用,缓存被引入,它变得不那么清晰。

我正在使用
seesaw
并将集合传递到
seesaw.graphics/draw
以绘制一系列线
draw
shape
style
作为参数,因此当前的集合由交替的
seesaw.graphics/polygon
对象和描述样式的地图组成。我是否应该将此添加到问题中(我想让它更一般)?
draw
在处理其参数时使用
first
second
next
,因此列表可能会更好。你可以两者都计时。你有多少对(线+样式)?至少有几万对,可能超过100k。在我的计算机上,一个100k向量上的一个循环需要11毫秒,一个列表需要9毫秒。作为@akond imlies,不要浪费时间去考虑向量和列表之间的微观差异。此外,任何在屏幕上画画的东西都要比在内存中摆弄东西多花1000倍的时间。