我想知道为什么我用这两对递归的明显例子得到了意想不到的表现。
相同的递归函数在结构中更快(rec2 VS rec1),相同的递归模板函数在虚拟参数中更快(rec4 VS rec3)!
使用更多参数的C++函数是否更快?!
下面是尝试的代码:
#include <QDebug>
#include <QElapsedTimer>
constexpr std::size_t N = 28;
std::size_t counter = 0;
// non template function which take 1 argument
void rec1(std::size_t depth)
{
++counter;
if ( depth < N )
{
rec1(depth + 1);
rec1(depth + 1);
}
}
// non template member which take 2 arguments (implicit this)
struct A
{
void rec2(std::size_t depth)
{
++counter;
if ( depth < N )
{
rec2(depth + 1);
rec2(depth + 1);
}
}
};
// template function which take 0 argument
template <std::size_t D>
void rec3()
{
++counter;
rec3<D - 1>();
rec3<D - 1>();
}
template <>
void rec3<0>()
{
++counter;
}
// template function which take 1 (dummy) argument
struct Foo
{
int x;
};
template <std::size_t D>
void rec4(Foo x)
{
++counter;
rec4<D - 1>(x);
rec4<D - 1>(x);
}
template <>
void rec4<0>(Foo x)
{
++counter;
}
int main()
{
QElapsedTimer t;
t.start();
rec1(0);
qDebug() << "time1" << t.elapsed();
qDebug() << "counter" << counter;
counter = 0;
A a;
t.start();
a.rec2(0);
qDebug()<< "time2" << t.elapsed();
qDebug()<< "counter" << counter;
counter = 0;
t.start();
rec3<N>();
qDebug()<< "time3" << t.elapsed();
qDebug()<< "counter" << counter;
counter = 0;
t.start();
rec4<N>(Foo());
qDebug()<< "time4" << t.elapsed();
qDebug()<< "counter" << counter;
qDebug() << "fin";
return 0;
}
我得到这样的输出:
time1 976
counter 536870911
time2 341
counter 536870911
time3 241
counter 536870911
time4 201
counter 536870911
fin
我已启用:Windows 8.1/i7 3630QM/Latch Qt ChainTool/C++14
我终于能够在Visual Studio2015社区上看到这一点。检查已编译代码的反汇编,rec1和rec2是递归的。它们在生成的代码中非常相似,尽管rec2有更多的指令,但它运行的速度略快。rec3和rec4都为模板参数中的D的所有不同值生成一系列函数,在这种情况下,编译器消除了许多函数调用,消除了其他函数调用,并添加了一个较大的值来计数。(例如,rec4<10>只是将2047添加到count并返回。)
因此,您看到的性能差异主要是由于编译器如何优化每个版本,而代码如何流经CPU的细微差异也是一个因素。
我的结果(以秒为单位的时间),用/ox/O2编译:
time1 1.03411
counter 536870911
time2 0.970455
counter 536870911
time3 0.000866
counter 536870911
time4 0.000804
counter 536870911
问题内容: 开放赏金:好吧,老板需要答案,我需要加薪。这似乎不是一个冷缓存问题。 更新: 我没有遵循以下建议。客户统计数据如何得出一组有趣的数字。 #temp 与 @temp INSERT,DELETE和UPDATE语句的数量0对1 受INSERT,DELETE或UPDATE语句影响的行0 vs 7647 SELECT语句数0 vs 0 SELECT语句返回的行0 vs 0 交易数量0对1 最有趣
各种各样的书籍、文章、博客帖子表明,将递归函数重写为尾部递归函数可以加快速度。毫无疑问,对于生成斐波那契数或计算阶乘等琐碎情况,它会更快。在这种情况下,有一种典型的重写方法,即使用“辅助函数”和用于中间结果的附加参数。 尾部递归很好地描述了尾部递归函数和非尾部递归函数之间的差异,以及如何将递归函数转换为尾部递归函数。对于这种重写来说什么是重要的-函数调用的数量是相同的(重写之前/之后),不同之处在
在我看来,我的缓冲区包含关于最后一个数据包步骤(路由器->my home)的信息,这些信息解释了为什么TTL值是254以及为什么我用Traceroute找到了相同的两个IP: $>traceroute qwant.com traceroute to qwant.com(194.187.168.99),30跳最大,60字节数据包 172.17.0.1(172.17.0.1)0.026 ms 0.01
本文向大家介绍数据结构 二叉树的递归与非递归,包括了数据结构 二叉树的递归与非递归的使用技巧和注意事项,需要的朋友参考一下 数据结构 二叉树的递归与非递归 实例代码: 先序遍历(递归法) 后序遍历 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
问题内容: 给定一个变量,该变量包含巴黎时区的日期时间2000-01-01 00:01(冬季afaik中为UTC + 2): 我希望转换为UTC会导致日期时间为1999-12-31 22:01,但是却得到了: 我想念什么? 谢谢 问题答案: 不幸的是 ,在许多时区使用标准构造函数的参数“不起作用” 。 但是对于没有夏令时转换的时区来说是安全的,例如UTC: 您会注意到: “ LMT + 0:09:
我有以下代码: 为什么它会打印Java流?