当在Scheme中递归地构建列表时,看到两种类型的示例分散在互联网上。每次迭代都会在append
附加一个新值。另一个在cons
每次迭代之前都有一个新值,然后在列表完成后reverse
被调用一次。
我的直觉是后者更快,但如果Scheme解释器缓存了列表指针的末尾或正在进行其他优化,那么前者将同样快速且可读性更高。如果解释器正在进行此优化,是否保证在所有解释器中都可用?
答案 0 :(得分:5)
始终首选使用cons
。使用append
是非常低效的,因为它总是遍历列表到最后只是为了在那里添加一个新元素,而cons
在开头添加元素。没有指向列表末尾的指针,因此您建议的优化根本不会执行。
逐个元素构建大型列表时,这很重要,因为cons
是O(1)
操作,而append
是O(n)
,每个新元素都添加了,降级到O(n^2)
复杂度! (有一个很好的类比,请参阅:Schlemiel the Painter's algorithm)。最后,简单地在开头添加元素要便宜得多,如有必要reverse
最后的列表,实现O(n)
复杂性。