如何获得一个c++代码段执行时间的客观评价

How to get an objective evaluation of the execution time of a C++ code snippet?

本文关键字:代码 执行时间 评价 客观 c++ 一个 何获得      更新时间:2023-10-16

我一直在看《如何计算c++代码段的执行时间》这篇文章,这篇文章给出了计算代码段执行时间的一个很好的解决方案。然而,当我使用这个解决方案来测量我的代码片段在linux中的执行时间时,我发现我运行的每一个程序,解决方案给出的执行时间都是不同的。所以我的问题是如何客观地评估执行时间。客观评估对我来说很重要,因为我使用以下方案来评估同一任务的不同实现:

void main()
{
int64 begin,end; 
begin = GetTimeMs64();
execute_my_codes_method1();
end = GetTimeMs64();
std::cout<<"Execution time is "<<end-begin<<std::endl;
}

首先,我运行上面的代码来获得第一个方法的执行时间。之后,我将通过调用execute_my_codes_method2()来更改上述代码,并获得第二个方法的执行时间。

 void main()
    {
    int64 begin,end; 
    begin = GetTimeMs64();
    execute_my_codes_method2();//execute_my_codes_method1();
    end = GetTimeMs64();
    std::cout<<"Execution time is "<<end-begin<<std::endl;
    }

通过比较不同的执行时间,我希望比较这两种不同实现的效率。

我更改代码并运行不同实现的原因是因为在一个程序中顺序调用它们非常困难。因此,对于同一个程序,在不同的时间运行它会导致不同的执行时间,这意味着使用计算的执行时间来比较不同的实现方法是没有意义的。对这个问题有什么建议吗?谢谢。

衡量单个调用的执行时间对于判断任何性能改进是毫无用处的。影响函数实际执行时间的因素太多了。如果要测量计时,则应该对函数进行多次调用,测量时间并构建测量执行时间的统计平均值

void main() {
    int64 begin = 0, end = 0; 
    begin = GetTimeMs64();
    for (int i = 0; i < 10000; ++i) {
        execute_my_codes_method1();
    }
    end = GetTimeMs64();
    std::cout<<"Average execution time is "<< (end - begin) / 10000 << std::endl;
}

另外,与上面所示的不同,预先为你的函数进行单元测试(使用一个体面的测试框架,比如Google Test),将使你更快、更容易地做出这样的快速判断。

您不仅可以确定应该运行测试用例的频率(收集用于平均时间计算的统计数据),单元测试还可以证明期望的/现有的功能和输入/输出一致性没有被替代实现破坏。

作为一个额外的好处(正如您提到的顺序运行两个函数的困难),大多数单元测试框架允许有SetUp()TearDown()方法,它们在运行测试用例之前/之后执行。因此,您可以很容易地为运行的每个测试用例提供一致的谓词状态或不变条件。


作为进一步的选择,您可以使用通过代码插装工作的分析工具,而不是自己测量来收集统计数据。GCC的gprof就是一个很好的例子。我认为收集到的信息包括每个底层函数被调用的频率以及执行所花费的时间。这些数据可以在以后使用该工具进行分析,以在实现中找到潜在的瓶颈

另外,如果你决定在将来提供单元测试,你可能想要确保你所有的代码路径关于不同的输入数据情况都被你的测试用例很好地覆盖了。关于如何做到这一点,一个很好的例子是GCC的gcov工具。要分析收集到的关于代码覆盖率的信息,您可以使用lcov,它可以很好地将结果可视化,并且非常全面。