[英]Why is the sort in lisp faster for lists than arrays?
我以为我应该在顺序处理序列时更喜欢列表,如果需要随机访问元素,则更喜欢数组。
因此,我写了几行代码来确认我的想法。 首先,我编写了一个函数来测试多个点。 它显示它在列表中运行更快。
但是后来我尝试了排序功能。 由于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中的数组有效得多?
我无法复制它。
在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
因此,三个符号的向量也是元素类型为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
除了已经说过的关于数组与列表的讨论之外,还没有所谓的“最快”排序算法。 这最终取决于您要排序的数据。 一些算法在包含相似值的集合上表现更好,而其他算法在包含几乎排序的值的集合上表现更好。
实际上,可能还有其他复杂性,例如在排序过程中创建的其他问题或在数组排序过程中分配的其他内存。 需要调用GC的某些事情可能会完全扭转潮流。
每当您遇到需要排序的特殊实际问题时,就需要考虑具体情况以及将要处理的数据类型。 例如,在渲染动画时在3维空间中对Z顶点进行排序最可能会受益于对链表和几乎排序的数据进行操作的算法,而对气象研究数据的排序可能会受益于处理以下问题的最佳算法:以前未排序的大多是唯一数据。 某些特定的软件可以执行矢量化插入排序,这将比每个运算算法的任何单个值快许多倍,依此类推。
对随机数集合进行排序通常不能很好地指示代码将如何对实际数据执行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.