为什么列表中的排序比列表更快?

时间:2012-10-21 23:47:55

标签: arrays list lisp

我认为顺序处理序列时我应该更喜欢列表,如果需要随机访问元素,我更喜欢数组。

所以,我写了几行代码来证实我的想法。首先,我编写了一个测试点倍数的函数。它显示它在列表中运行得更快。

但后来我尝试了排序功能。由于sort函数需要随机访问元素,我希望它在数组中运行得更快。但结果恰恰相反。

(defun test-performance-map-mapcar ()
  (let* ((lst (generate-random 1000000))
     (arr (lst-to-arr lst)))
    (time (atom (sort lst #'>)))
    (time (atom (sort arr #'>)))))

那么,它是排序函数应用某种算法来适应列表或列表真的比lisp中的数组更有效吗?

2 个答案:

答案 0 :(得分:4)

我无法重现它。

随机数的排序向量比在LispWorks中排序随机数列表要快。

(defun test ()
  (let* ((list (loop repeat 10000000 collect (random 1000000)))
         (vector (coerce list 'vector)))
    (time (sort list #'>))
    (time (sort vector #'>))
    (values)))

示例:

CL-USER 9 > (test)
Timing the evaluation of (SORT LIST (FUNCTION >))

User time    =        8.697
System time  =        0.027
Elapsed time =        8.626
Allocation   = 170168 bytes
145 Page faults
Timing the evaluation of (SORT VECTOR (FUNCTION >))

User time    =        5.951
System time  =        0.018
Elapsed time =        5.904
Allocation   = 120512 bytes
86 Page faults

向量为5.951秒,列表为8.697。

在Common Lisp中,一维数组正好是向量。 SORT也不适用于其他多维数组。

CL-USER 10 > (vector 'a 'b 'c)
#(A B C)

CL-USER 11 > (describe *)

#(A B C) is a (SIMPLE-VECTOR 3)
0      A
1      B
2      C

CL-USER 12 > (arrayp **)
T

CL-USER 13 > (typep (vector 'a 'b 'c) '(array symbol (3)))
T

因此,三个符号的向量也是一个长度为3的一维数组,其元素类型为SYMBOL

对于我的例子(带有Intel i7处理器的Apple Macbook Air):

Implementation   | faster | seconds
-----------------+--------+--------
LispWorks 64bit  | vector |  5.951
Clozure CL 64bit | vector |  6.727
SBCL 1.1 64bit   | list   |  8.890
CLISP            | list   | 42.968

答案 1 :(得分:3)

除了已经说过的有关数组与列表的内容之外,还没有"最快"排序算法。这最终取决于您排序的数据。某些算法在包含相似值的集合上表现更好,而其他算法在包含近似排序值的集合上表现更好。

实际上,可能还有其他复杂情况,例如,在排序期间创建的其他conses或在数组排序期间分配的额外内存。需要调用GC的东西,这可能会完全扭转潮汐。

每当您遇到需要排序的特定实际问题时,您需要考虑环境以及您将要处理的数据类型。例如,在渲染动画的同时对三维空间中的Z顶点进行排序可能最有利于对链接列表和几乎排序的数据进行操作的算法,对气象研究数据的排序可能会受益于最佳处理的算法以前未分类的大多数是唯一数据某些特定软件可以进行矢量化插入排序,其速度比每个操作算法的单个值快许多倍,等等。

对随机数的集合进行排序通常不能很好地指示代码在实际数据上的表现。