【发布时间】:2017-01-08 15:30:17
【问题描述】:
在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++ 很陌生)
【问题讨论】:
-
你为什么不试试两者并告诉我们你发现了什么?
-
尾递归可以带来不错的、干净的解决方案,但你最好希望你的编译器将其优化为循环而不是递归(如果通过了必要的优化标志,几乎所有编译器都会这样做,但是如果关闭优化(例如在调试版本中),可能不会)。否则,如果您搜索长列表,可能会出现堆栈溢出。
-
@Kerrek 我是来自 python 背景的 c++ 新手,我还不熟悉 cprofile 或编译过程,但你是对的,我当然应该自己尝试一下。刚刚看到你的例子谢谢你告诉我这个!
-
@YuhaoTigerHuang:我总是觉得人们想讨论一些他们实际上似乎不太感兴趣的事情很好奇。如果你确实关心 C++ 编译器如何生成代码,你会 a)对机器代码有一些兴趣(因此您甚至可以连贯地表达您的兴趣),并且 b) 了解如何检查编译器输出(例如
gcc -S或配置文件)。否则,如果您对这些事情没有特别的兴趣,那么只需使用您更喜欢的代码,直到您真正遇到会迫使您产生兴趣的问题。
标签: c++ recursion iterator non-recursive accelerated-c++