当前位置: 首页 > 知识库问答 >
问题:

在C中测量函数的执行时间

桑坚
2023-03-14

我想知道在我的C程序中,某个函数在Linux上执行需要多少时间。之后,我想做一个速度比较。我看到了几个时间函数,但最后从boost得到了这个结果。计时:

process_user_cpu_clock, captures user-CPU time spent by the current process

现在,我不清楚如果我使用上述功能,我会得到CPU在该功能上花费的唯一时间吗?

其次,我找不到任何使用上述功能的例子。请帮助我如何使用上述功能?

P.S:现在,我正在使用std::chrono::system_clock::now()以秒为单位获取时间,但由于每次CPU负载不同,这给了我不同的结果。

共有3个答案

符俊材
2023-03-14

在Scott Meyers的书中,我找到了一个通用通用lambda表达式的示例,该表达式可用于测量函数执行时间。(C 14)

auto timeFuncInvocation = 
    [](auto&& func, auto&&... params) {
        // get time before function invocation
        const auto& start = std::chrono::high_resolution_clock::now();
        // function invocation using perfect forwarding
        std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
        // get time after function invocation
        const auto& stop = std::chrono::high_resolution_clock::now();
        return stop - start;
     };

问题是您只测量了一次执行,因此结果可能非常不同。为了获得可靠的结果,您应该测量大量的执行。根据Andrei Alexandrescu在code::dive 2015会议上的演讲-编写快速代码I:

测量时间:tm = t tq tn to

哪里:

tm-测量(观测)时间

t-实际关注时间

tq -量化噪声增加的时间

tn -各种噪声源增加的时间

to-开销时间(测量、循环、调用函数)

根据他后来在讲座中所说的话,你应该把这大量的处决作为你的结果。我鼓励你看看他解释为什么的讲座。

谷歌也有一个非常好的库-https://github.com/google/benchmark.这个库使用起来非常简单,功能强大。你可以在youtube上查看钱德勒·卡鲁斯的一些讲座,他在实践中使用了这个库。例如CppCon 2017:钱德勒·卡鲁斯“无处可去”;

用法示例:

#include <iostream>
#include <chrono>
#include <vector>
auto timeFuncInvocation = 
    [](auto&& func, auto&&... params) {
        // get time before function invocation
        const auto& start = high_resolution_clock::now();
        // function invocation using perfect forwarding
        for(auto i = 0; i < 100000/*largeNumber*/; ++i) {
            std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
        }
        // get time after function invocation
        const auto& stop = high_resolution_clock::now();
        return (stop - start)/100000/*largeNumber*/;
     };

void f(std::vector<int>& vec) {
    vec.push_back(1);
}

void f2(std::vector<int>& vec) {
    vec.emplace_back(1);
}
int main()
{
    std::vector<int> vec;
    std::vector<int> vec2;
    std::cout << timeFuncInvocation(f, vec).count() << std::endl;
    std::cout << timeFuncInvocation(f2, vec2).count() << std::endl;
    std::vector<int> vec3;
    vec3.reserve(100000);
    std::vector<int> vec4;
    vec4.reserve(100000);
    std::cout << timeFuncInvocation(f, vec3).count() << std::endl;
    std::cout << timeFuncInvocation(f2, vec4).count() << std::endl;
    return 0;
}

编辑:当然,你总是需要记住,你的编译器可以优化一些东西,或者不优化一些东西。在这种情况下,像perf这样的工具可能很有用。

隗翰海
2023-03-14

这里有一个函数,它将测量作为参数传递的任何函数的执行时间:

#include <chrono>
#include <utility>

typedef std::chrono::high_resolution_clock::time_point TimeVar;

#define duration(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

template<typename F, typename... Args>
double funcTime(F func, Args&&... args){
    TimeVar t1=timeNow();
    func(std::forward<Args>(args)...);
    return duration(timeNow()-t1);
}

用法示例:

#include <iostream>
#include <algorithm>

typedef std::string String;

//first test function doing something
int countCharInString(String s, char delim){
    int count=0;
    String::size_type pos = s.find_first_of(delim);
    while ((pos = s.find_first_of(delim, pos)) != String::npos){
        count++;pos++;
    }
    return count;
}

//second test function doing the same thing in different way
int countWithAlgorithm(String s, char delim){
    return std::count(s.begin(),s.end(),delim);
}


int main(){
    std::cout<<"norm: "<<funcTime(countCharInString,"precision=10",'=')<<"\n";
    std::cout<<"algo: "<<funcTime(countWithAlgorithm,"precision=10",'=');
    return 0;
}

输出:

norm: 15555
algo: 2976
南宫建白
2023-03-14

在C 11中是一个非常容易使用的方法,你必须使用std::chrono::high_resolution_clockfrom

按如下方式使用:

#include <chrono>

/* Only needed for the sake of this example. */
#include <iostream>
#include <thread>
    
void long_operation()
{
    /* Simulating a long, heavy operation. */

    using namespace std::chrono_literals;
    std::this_thread::sleep_for(150ms);
}

int main()
{
    using std::chrono::high_resolution_clock;
    using std::chrono::duration_cast;
    using std::chrono::duration;
    using std::chrono::milliseconds;

    auto t1 = high_resolution_clock::now();
    long_operation();
    auto t2 = high_resolution_clock::now();

    /* Getting number of milliseconds as an integer. */
    auto ms_int = duration_cast<milliseconds>(t2 - t1);

    /* Getting number of milliseconds as a double. */
    duration<double, std::milli> ms_double = t2 - t1;

    std::cout << ms_int.count() << "ms\n";
    std::cout << ms_double.count() << "ms\n";
    return 0;
}

这将测量函数long_operation的持续时间。

可能的输出:

150ms
150.068ms

工作示例:https://godbolt.org/z/oe5cMd

 类似资料:
  • 问题内容: 我需要获取执行时间(以毫秒为单位)。 我最初在2008年问这个问题。当时接受的答案是使用。new Date().getTime()但是,我们大家都可以同意,使用标准performance.now()API更合适。因此,我正在更改对此答案的公认答案。 问题答案: 使用 : NodeJs:需要导入performance类 使用:(非标准)(生活水平)

  • 问题内容: 我需要获取执行时间(以毫秒为单位)。 当时接受的答案是使用newDate()。getTime()。但是,我们现在都可以同意使用标准performance.now()API更合适。因此,我正在更改对此答案的公认答案。 问题答案: 使用 performance.now(): :需要导入类 使用 console.time: (非标准) (living standard) 注意 : 传递给和方

  • 问题内容: 请告诉我,如何在C 代码中包含javascript头文件或javascript函数。 C 代码是用Linux(UBUNTU)编写的吗? 尽管我仅需要执行上述操作,但是由于我打算实现CTI(计算机电话集成)操作,因此请告诉我我的操作目的。 (将不胜感激)非常感谢 问题答案: 从C ++调用脚本函数 http://clipp.sourceforge.net/Tutorial/back_ca

  • 问题内容: 有什么方法可以从C#执行Go函数吗?对于Python,我将使用Ironpython为例。 我知道我可以产生一个执行Go脚本的过程,但是如果可能的话,我真的不想回退到这种解决方案。 Google搜索没有显示任何内容,因此有什么方法可以使用API​​做到这一点?还是我必须回退流程? 问题答案: 编辑:我的答案现在是不正确的,因为自从我发布以来,Go已经更新。 这个stackoverflow

  • 利用Console API来测量执行时间和计数语句执行。 TL;DR 使用console.time()和console.timeEnd()测量代码两个执行点之间所需的时间。 使用console.count()来计算同一个字符串传递给函数的次数。 测量执行时间 time()方法启动一个新的计时器,对于测量代码执行时间来说是=是非常有用的。将字符串传递给该方法,来给测量标记一个名称。 当您想停止计时器

  • 我想比较一个函数的不同实现: 我得到的结果是,第一个度量值总是比第二个慢(