"find" 的递归版本和非递归版本有什么区别?
what is the difference between a recursive version of "find" and a not recursive one?
在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 建议的编译器资源管理器,我得到了以下结果
非递归https://godbolt.org/g/waKUF2
递归https://godbolt.org/g/VKNnYZ
编译后好像一模一样? (如果我正确使用该工具..抱歉,我是 C++ 的新手)
在大多数情况下,递归速度较慢,并且占用的堆栈也更多。递归的主要优点是对于像树遍历这样的问题,它使算法更容易或更容易 "elegant"。
查看一些比较:
Recursion vs Iteration
递归函数会在堆栈上添加额外的元素。这可能会导致 Whosebug 错误,具体取决于开始递归之前堆栈的状态和递归的次数。
每个函数调用都会将数据压入堆栈,其中包括 return 地址。这一直持续到找到数据为止。此时,所有函数都将开始 return 最后一个函数 return 编辑的值,直到我们最终回到调用原始 find
.[=11 的函数=]
为每个函数调用存储的确切数据量取决于调用约定和体系结构。将数据推入堆栈也会产生开销,这会使算法变慢,但这取决于算法。
这严格适用于未优化尾调用的递归。
在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 建议的编译器资源管理器,我得到了以下结果
非递归https://godbolt.org/g/waKUF2
递归https://godbolt.org/g/VKNnYZ
编译后好像一模一样? (如果我正确使用该工具..抱歉,我是 C++ 的新手)
在大多数情况下,递归速度较慢,并且占用的堆栈也更多。递归的主要优点是对于像树遍历这样的问题,它使算法更容易或更容易 "elegant"。
查看一些比较: Recursion vs Iteration
递归函数会在堆栈上添加额外的元素。这可能会导致 Whosebug 错误,具体取决于开始递归之前堆栈的状态和递归的次数。
每个函数调用都会将数据压入堆栈,其中包括 return 地址。这一直持续到找到数据为止。此时,所有函数都将开始 return 最后一个函数 return 编辑的值,直到我们最终回到调用原始 find
.[=11 的函数=]
为每个函数调用存储的确切数据量取决于调用约定和体系结构。将数据推入堆栈也会产生开销,这会使算法变慢,但这取决于算法。
这严格适用于未优化尾调用的递归。