c++ - 如何测试两种算法并确定哪种算法更快?

标签 c++ benchmarking

每当处理一个特定问题时,我可能会遇到不同的解决方案。我不确定如何选择两个选项中更好的一个。第一个想法是计算两个解决方案的复杂性,但有时它们可​​能具有相同的复杂性,或者它们可能不同但输入的范围很小,因此常数因子很重要。

第二个想法是对这两种解决方案进行基准测试。但是,我不确定如何使用 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;
}

最佳答案

使用来自 this answer 的时钟

#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) 的情况下进行编译,只是为了看看有什么区别。在最大优化下,编译器可能会完全消除循环。

关于c++ - 如何测试两种算法并确定哪种算法更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49519382/

相关文章:

c++ - 从使用 SDL_TTF 创建的 SDL2 表面提取像素

c++ - `static_cast<volatile void>` 对优化器意味着什么?

c++ - 在 MinGW 中使用 Boost 时出现问题

c++ - POD 与非 POD 类类型的默认初始化

c++ - 有什么方法可以将基类型存储在变量或成员指针中?

c++ - 为什么 std::round(sin(pi/6)) 不等于 1?

c++ - 对一段独立于 CPU 性能的代码进行基准测试?

java - 在 Java + Linux 中,测量跨 CPU 内核延迟的正确方法是什么?

java - 基准测试中可能出现不需要的编译器优化

java - JMH @Fork 的目的是什么?