Common Lisp的最佳做法,我有合并两个符号有序列表一个Common Lisp的功能,无需重复(两个有序集):使用类型声明进行优化
(defun my-merge (x y)
"merge two lists of symbols *already sorted and without duplicates*
(and return the resulting list sorted and without duplicates)"
(let* ((first (cons nil nil))
(last first))
(loop while (and x y)
for cx = (car x)
for cy = (car y)
if (string= cx cy)
do (setf x (cdr x))
else if (string< cx cy)
do (rplacd last (cons cx nil))
and do (setf last (cdr last)
x (cdr x))
else do (rplacd last (cons cy nil))
and do (setf last (cdr last)
y (cdr y)))
(rplacd last (or x y))
(cdr first)))
既然我已经发现了大约只有很少的信息为了有效地编译代码的使用实际情况类型声明的,我不能确定它是否足够以这种方式声明变量,例如:
(defun my-merge (x y)
"merge two list of symbols *already sorted and without duplicates*"
(declare (list x y))
(let* ((first (cons nil nil))
(last first))
(declare (cons first last))
(loop while (and x y)
for cx symbol = (car x)
for cy symbol = (car y)
...
,或者因为我想,如果是还需要添加the
说明符到我的代码?但那么,其中和哪些情况下应该加吗?
有一些规则可以遵循?
我是否还应该为我的优化目的声明我的函数的类型?
优化,使用典型值的优化和类型推断的声明完全是特定于实现的。你会在实现中找到所有的东西:从基于类型声明的零优化,使用类型声明,甚至是*类型推断*(这意味着需要更少的类型声明)。通常:声明类型并进行优化,然后查看生成的汇编程序和/或测量时间。如果你使用SBCL,CMUCL或者LispWorks,编译器会(或者可以配置为)告诉你它不能优化的地方以及为什么。然后会添加必要的声明。 –
推出自己的解决方案总是很有趣,但请注意,最好的选择之一可能就是使用标准[** merge **](http://www.lispworks.com/documentation/HyperSpec/Body/) f_merge.htm)函数。它可以产生任意的序列类型,采用任意的谓词等,并且实现可能已经优化了它(可能值得查看它们的来源)。 –
@JoshuaTaylor,这是我的第一选择,但后来我测试了SBCL和CCL的合并函数,它们是我目前使用的实现,并且* both *在大型列表上的性能明显最差(不记得确切的数字)。我也不知道其中的原因,或者我在执行测试时做了错误。 – Renzo