每当处理特定问题时,我都会遇到不同的解决方案。我不确定如何选择两种选择中较好的一种。第一个想法是计算两个解决方案的复杂性,但有时它们可能共享相同的复杂性,或者它们可能不同,但输入的范围很小,而常数因素很重要。
第二个想法是对两种解决方案进行基准测试。但是,我不确定如何使用c ++计时。我发现了这个问题: How to Calculate Execution Time of a Code Snippet in C++,但我不知道如何正确处理编译器优化或处理器不一致。
简而言之:上述问题中提供的代码是否足以进行日常测试?在运行测试之前,我是否应该在编译器中启用一些选项? (我使用的是Visual C ++)我应该做多少次测试,两个基准测试之间的时差有多大?
以下是我要测试的代码示例。哪个更快?我怎么能自己计算呢?
unsigned long long fiborecursion(int rank){
if (rank == 0) return 1;
else if (rank < 0) return 0;
return fiborecursion(rank-1) + fiborecursion(rank-2);
}
double sq5 = sqrt(5);
unsigned long long fiboconstant(int rank){
return pow((1 + sq5) / 2, rank + 1) / sq5 + 0.5;
}
答案 0 :(得分:2)
#include <iostream>
#include <chrono>
class Timer
{
public:
Timer() : beg_(clock_::now()) {}
void reset() { beg_ = clock_::now(); }
double elapsed() const {
return std::chrono::duration_cast<second_>
(clock_::now() - beg_).count(); }
private:
typedef std::chrono::high_resolution_clock clock_;
typedef std::chrono::duration<double, std::ratio<1> > second_;
std::chrono::time_point<clock_> beg_;
};
您可以编写一个程序来计算两个函数的时间。
int main() {
const int N = 10000;
Timer tmr;
tmr.reset();
for (int i = 0; i < N; i++) {
auto value = fiborecursion(i%50);
}
double time1 = tmr.elapsed();
tmr.reset();
for (int i = 0; i < N; i++) {
auto value = fiboconstant(i%50);
}
double time2 = tmr.elapsed();
std::cout << "Recursion"
<< "\n\tTotal: " << time1
<< "\n\tAvg: " << time1 / N
<< "\n"
<< "\nConstant"
<< "\n\tTotal: " << time2
<< "\n\tAvg: " << time2 / N
<< "\n";
}
我会尝试编译,不需要编译器优化(-O0
)和最大编译器优化(-O3
),只是为了看看它们之间的区别。在最大优化时,编译器可能会完全消除循环。