在 Accelerated C ++ Programming 一书中,第205页,find
template <class In, class X> In find(In begin, In end, const X& x)
我很想知道以下两个实现在性能方面有什么不同(编译后是否真的相同?)。
非递归
template <class In, class X> In find(In begin, In end, const X& x)
{
while (begin != end && *begin != x)
++begin;
return begin;
}
递归
template <class In, class X> In find(In begin, In end, const X& x)
{
if (begin == end || *begin == x)
return begin;
begin++;
return find(begin, end, x);
}
通过使用Kerrek建议的Compiler Explorer,我得到了以下内容
非递归https://godbolt.org/g/waKUF2
递归https://godbolt.org/g/VKNnYZ
编译后似乎完全一样? (如果我正确使用该工具..对不起,我是C ++的新手)
答案 0 :(得分:1)
递归函数将在堆栈上添加额外的元素。这可能会导致堆栈溢出错误,具体取决于在开始递归之前堆栈的状态以及递归的次数。
每个函数调用将数据推送到包含返回地址的堆栈。这一直持续到找到数据为止。此时,所有函数将开始返回最后一个函数返回的值,直到我们最终返回到调用原始find
的函数。
为每个函数调用存储的确切数据量取决于调用约定和体系结构。在堆栈上推送数据也会产生开销,这会使算法变慢,但这取决于算法。
这严格用于非尾调用优化的递归。
答案 1 :(得分:0)
在大多数情况下,递归速度较慢,并且占用了更多的堆栈。递归的主要优点是,对于像树遍历这样的问题,它使算法更容易或更“优雅”。
查看一些比较: Recursion vs Iteration