轻松测量经过的时间

hap*_*497 272 c c++ linux time measurement

我正在尝试使用time()来衡量我的程序的各个点.

我不明白为什么之前和之后的值是一样的?我知道这不是描述我的程序的最佳方式,我只想看看有多长时间.

printf("**MyProgram::before time= %ld\n", time(NULL));

doSomthing();
doSomthingLong();

printf("**MyProgram::after time= %ld\n", time(NULL));
Run Code Online (Sandbox Code Playgroud)

我试过了:

struct timeval diff, startTV, endTV;

gettimeofday(&startTV, NULL); 

doSomething();
doSomethingLong();

gettimeofday(&endTV, NULL); 

timersub(&endTV, &startTV, &diff);

printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);
Run Code Online (Sandbox Code Playgroud)

我如何阅读结果**time taken = 0 26339?这是否意味着26,339纳秒= 26.3毫秒?

那怎么说**time taken = 4 45025,这意味着4秒和25毫秒?

小智 266

#include <ctime>

void f() {
  using namespace std;
  clock_t begin = clock();

  code_to_time();

  clock_t end = clock();
  double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
}
Run Code Online (Sandbox Code Playgroud)

time()功能仅精确到一秒钟内,但在一秒钟内有CLOCKS_PER_SEC"时钟".这是一种简单,便携的测量方法,即使它过于简单.

  • 请注意`clock()`测量CPU时间,而不是实际经过的时间(可能更大). (125认同)
  • 在为集群编写并行代码时,此方法不能反映实际时间...... (12认同)
  • 由于许多原因,上面发布的解决方案不是一个好的解决方案 这是正确答案 - http://stackoverflow.com/questions/2962785/c-using-clock-to-measure-time-in-multi-threaded-programs/2962914#2962914 (5认同)
  • 这似乎是最简单的方法.您是否愿意更新或解决@jlstrecker发表的评论? (3认同)

use*_*106 265

//***C++11 Style:***
#include <chrono>

std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << "[µs]" << std::endl;
std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::nanoseconds> (end - begin).count() << "[ns]" << std::endl;
Run Code Online (Sandbox Code Playgroud)

  • 要运行它,你必须添加`#include <chrono>`指令,我会将报告时间改为:`std :: cout <<"时差(秒)="<<(std :: chrono :: duration_cast <std :: chrono :: microseconds>(end - begin).count())/ 1000000.0 << std :: endl;`(编译时不要忘记C++ 11标志:`-std = c ++ 11`) (18认同)
  • 我觉得这个很简单,对我有用. (16认同)
  • 是的,这应该是答案 (9认同)
  • @ RestlessC0bra根据cppreference上的文档,"这个时钟与挂钟时间无关(例如,它可能是自上次重启以来的时间),并且最适合测量间隔." (4认同)
  • 这是什么数据类型?std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(end - begin).count() (4认同)
  • @AxelRietschin 那只会返回以秒为单位的时间。安东内洛的建议还提供了分数时间(即“2.15315”秒而不是“2”秒)。 (2认同)

Nik*_*iou 261

您可以抽象时间测量机制,并使用最少的额外代码测量每个可调用的运行时间,只需通过计时器结构调用即可.另外,在编译时,您可以参数化时序类型(毫秒,纳秒等).

感谢Loki Astari的审核以及使用可变参数模板的建议. 就是转发函数调用的原因.

#include <iostream>
#include <chrono>

template<typename TimeT = std::chrono::milliseconds>
struct measure
{
    template<typename F, typename ...Args>
    static typename TimeT::rep execution(F&& func, Args&&... args)
    {
        auto start = std::chrono::steady_clock::now();
        std::forward<decltype(func)>(func)(std::forward<Args>(args)...);
        auto duration = std::chrono::duration_cast< TimeT> 
                            (std::chrono::steady_clock::now() - start);
        return duration.count();
    }
};

int main() {
    std::cout << measure<>::execution(functor(dummy)) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

Demo

根据Howard Hinnant的评论,我们最好不要逃离计时系统,直到我们不得不这样做.所以上面的类可以让用户count通过提供额外的静态方法手动调用(如C++ 14所示)

template<typename F, typename ...Args>
static auto duration(F&& func, Args&&... args)
{
    auto start = std::chrono::steady_clock::now();
    std::forward<decltype(func)>(func)(std::forward<Args>(args)...);
    return std::chrono::duration_cast<TimeT>(std::chrono::steady_clock::now()-start);
} 

// call .count() manually later when needed (eg IO)
auto avg = (measure<>::duration(func) + measure<>::duration(func)) / 2.0;
Run Code Online (Sandbox Code Playgroud)

并且最适合那些客户

"想要在I/O之前对一堆持续时间进行后处理(例如平均值)"


完整的代码可以在这里找到.我在此处记录基于计时器构建基准测试工具的尝试.


如果C++ 17 std::invoke可用,则execution可以像这样调用callable in :

invoke(forward<decltype(func)>(func), forward<Args>(args)...);
Run Code Online (Sandbox Code Playgroud)

提供指向成员函数的指针的callable.

  • <nitpick>:除非必须(避免使用`.count()`),否则不要逃离`chrono`系统.让客户端在被强制时调用`.count()`(比如I/O,这确实是不幸的).客户端可能希望在I/O之前(例如平均值)对一堆持续时间进行后处理,这最好在`chrono`系统中完成. (6认同)
  • @oliora这是一回事.我更喜欢`std :: forward <decltype(func)>(func)`因为它可以应用于泛型lambdas(`auto && func`)的参数,其中`F`在语法上不存在,并且很容易在实用程序宏中抽象` #define fw(arg)std :: forward <decltype(arg)>(arg)`我在我的基准库中做的(所以这是一个留下的句法,我在答案中没有详细说明) (3认同)
  • 尼斯; 我的代码中有类似的东西,但是使用不同的类接口:我有一个类(`code_timer`),它占用了开始时间(`std :: chrono :: system_clock :: now();`)构造函数,一个方法`code_timer :: ellapsed`,用于测量新的`now()`调用与构造函数中的调用之间的区别,以及`code_timer :: reset`方法,用于将开始时间重置为新的`now( )结果.为了在我的代码中测量仿函数的执行,我在类之外使用了一个自由函数.这允许测量从物体构造到异步呼叫结束的时间. (2认同)
  • 为什么不`std :: forward <F>(func)`? (2认同)

AKN*_*AKN 56

正如我从你的问题中看到的那样,看起来你想知道执行某段代码后经过的时间.我想你会很自然地看到第二个结果.如果是这样,请尝试使用difftime()如下所示的功能.希望这能解决你的问题.

#include <time.h>
#include <stdio.h>

time_t start,end;
time (&start);
.
.
.
<your code>
.
.
.
time (&end);
double dif = difftime (end,start);
printf ("Elasped time is %.2lf seconds.", dif );
Run Code Online (Sandbox Code Playgroud)

  • 时间总是只返回秒,因此它不能用于次秒测量. (9认同)
  • 这总是给我整数秒.这应该发生吗? (3认同)

Rvd*_*vdK 31

仅限Windows :(我发布此答案后添加了Linux标记)

您可以使用GetTickCount()来获取自系统启动以来经过的毫秒数.

long int before = GetTickCount();

// Perform time-consuming operation

long int after = GetTickCount();
Run Code Online (Sandbox Code Playgroud)

  • 我在linux上使用它.所以我不能使用GetTickCount()函数. (7认同)

vod*_*ang 13

time(NULL)函数将返回自1970年1月1日00:00起经过的秒数.因为,在程序的不同时间调用该函数,C++中的时间总是不同


phi*_*ant 12

time(NULL)返回自1970年1月1日00:00(大纪元)以来经过的秒数.因此,两个值之间的差异是您处理的秒数.

int t0 = time(NULL);
doSomthing();
doSomthingLong();
int t1 = time(NULL);

printf ("time = %d secs\n", t1 - t0);
Run Code Online (Sandbox Code Playgroud)

您可以获得更精细的结果getttimeofday(),以秒为单位返回当前时间,time()以及以微秒为单位.


小智 11

struct profiler
{
    std::string name;
    std::chrono::high_resolution_clock::time_point p;
    profiler(std::string const &n) :
        name(n), p(std::chrono::high_resolution_clock::now()) { }
    ~profiler()
    {
        using dura = std::chrono::duration<double>;
        auto d = std::chrono::high_resolution_clock::now() - p;
        std::cout << name << ": "
            << std::chrono::duration_cast<dura>(d).count()
            << std::endl;
    }
};

#define PROFILE_BLOCK(pbn) profiler _pfinstance(pbn)
Run Code Online (Sandbox Code Playgroud)

用法如下::

{
    PROFILE_BLOCK("Some time");
    // your code or function
}
Run Code Online (Sandbox Code Playgroud)

这与RAII的范围相似

注意这不是我的,但我认为这是相关的

  • 包括缺失的 (2认同)

小智 9

#include<time.h> // for clock
#include<math.h> // for fmod
#include<cstdlib> //for system
#include <stdio.h> //for delay

using namespace std;

int main()
{


   clock_t t1,t2;

   t1=clock(); // first time capture

   // Now your time spanning loop or code goes here
   // i am first trying to display time elapsed every time loop runs

   int ddays=0; // d prefix is just to say that this variable will be used for display
   int dhh=0;
   int dmm=0;
   int dss=0;

   int loopcount = 1000 ; // just for demo your loop will be different of course

   for(float count=1;count<loopcount;count++)
   {

     t2=clock(); // we get the time now

     float difference= (((float)t2)-((float)t1)); // gives the time elapsed since t1 in milliseconds

    // now get the time elapsed in seconds

    float seconds = difference/1000; // float value of seconds
    if (seconds<(60*60*24)) // a day is not over
    {
        dss = fmod(seconds,60); // the remainder is seconds to be displayed
        float minutes= seconds/60;  // the total minutes in float
        dmm= fmod(minutes,60);  // the remainder are minutes to be displayed
        float hours= minutes/60; // the total hours in float
        dhh= hours;  // the hours to be displayed
        ddays=0;
    }
    else // we have reached the counting of days
    {
        float days = seconds/(24*60*60);
        ddays = (int)(days);
        float minutes= seconds/60;  // the total minutes in float
        dmm= fmod(minutes,60);  // the rmainder are minutes to be displayed
        float hours= minutes/60; // the total hours in float
        dhh= fmod (hours,24);  // the hours to be displayed

    }

    cout<<"Count Is : "<<count<<"Time Elapsed : "<<ddays<<" Days "<<dhh<<" hrs "<<dmm<<" mins "<<dss<<" secs";


    // the actual working code here,I have just put a delay function
    delay(1000);
    system("cls");

 } // end for loop

}// end of main 
Run Code Online (Sandbox Code Playgroud)

  • 虽然您的答案很受欢迎,但我们更喜欢包含代码简要说明的前导码.谢谢. (3认同)
  • 这不是经过的时间,而是处理器时间. (2认同)

Did*_*set 8

第二个程序打印的值是秒和微秒.

0 26339 = 0.026'339 s =   26339 µs
4 45025 = 4.045'025 s = 4045025 µs
Run Code Online (Sandbox Code Playgroud)


Aka*_*pta 7

#include <ctime>
#include <cstdio>
#include <iostream>
#include <chrono>
#include <sys/time.h>
using namespace std;
using namespace std::chrono;

void f1()
{
  high_resolution_clock::time_point t1 = high_resolution_clock::now();
  high_resolution_clock::time_point t2 = high_resolution_clock::now();
  double dif = duration_cast<nanoseconds>( t2 - t1 ).count();
  printf ("Elasped time is %lf nanoseconds.\n", dif );
}

void f2()
{
  timespec ts1,ts2;
  clock_gettime(CLOCK_REALTIME, &ts1);
  clock_gettime(CLOCK_REALTIME, &ts2);
  double dif = double( ts2.tv_nsec - ts1.tv_nsec );
  printf ("Elasped time is %lf nanoseconds.\n", dif );
}

void f3()
{
  struct timeval t1,t0;
  gettimeofday(&t0, 0);
  gettimeofday(&t1, 0);
  double dif = double( (t1.tv_usec-t0.tv_usec)*1000);
  printf ("Elasped time is %lf nanoseconds.\n", dif );
}
void f4()
{
  high_resolution_clock::time_point t1 , t2;
  double diff = 0;
  t1 = high_resolution_clock::now() ;
  for(int i = 1; i <= 10 ; i++)
  {
    t2 = high_resolution_clock::now() ;
    diff+= duration_cast<nanoseconds>( t2 - t1 ).count();
    t1 = t2;
  }
  printf ("high_resolution_clock:: Elasped time is %lf nanoseconds.\n", diff/10 );
}

void f5()
{
  timespec ts1,ts2;
  double diff = 0;
  clock_gettime(CLOCK_REALTIME, &ts1);
  for(int i = 1; i <= 10 ; i++)
  {
    clock_gettime(CLOCK_REALTIME, &ts2);
    diff+= double( ts2.tv_nsec - ts1.tv_nsec );
    ts1 = ts2;
  }
  printf ("clock_gettime:: Elasped time is %lf nanoseconds.\n", diff/10 );
}

void f6()
{
  struct timeval t1,t2;
  double diff = 0;
  gettimeofday(&t1, 0);
  for(int i = 1; i <= 10 ; i++)
  {
    gettimeofday(&t2, 0);
    diff+= double( (t2.tv_usec-t1.tv_usec)*1000);
    t1 = t2;
  }
  printf ("gettimeofday:: Elasped time is %lf nanoseconds.\n", diff/10 );
}

int main()
{
  //  f1();
  //  f2();
  //  f3();
  f6();
  f4();
  f5();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*sky 5

C++ std::chrono 具有跨平台的明显优势。然而,与 POSIX Clock_gettime() 相比,它也带来了显着的开销。在我的 Linux 机器上,所有std::chrono::xxx_clock::now()版本的表现大致相同:

std::chrono::system_clock::now()
std::chrono::steady_clock::now()
std::chrono::high_resolution_clock::now()
Run Code Online (Sandbox Code Playgroud)

虽然 POSIXclock_gettime(CLOCK_MONOTONIC, &time)应该与 POSIX 相同steady_clock::now(),但速度快了 3 倍以上!

这是我的测试,为了完整性。

#include <stdio.h>
#include <chrono>
#include <ctime>

void print_timediff(const char* prefix, const struct timespec& start, const 
struct timespec& end)
{
    double milliseconds = end.tv_nsec >= start.tv_nsec
                        ? (end.tv_nsec - start.tv_nsec) / 1e6 + (end.tv_sec - start.tv_sec) * 1e3
                        : (start.tv_nsec - end.tv_nsec) / 1e6 + (end.tv_sec - start.tv_sec - 1) * 1e3;
    printf("%s: %lf milliseconds\n", prefix, milliseconds);
}

int main()
{
    int i, n = 1000000;
    struct timespec start, end;

    // Test stopwatch
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i) {
        struct timespec dummy;
        clock_gettime(CLOCK_MONOTONIC, &dummy);
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("clock_gettime", start, end);

    // Test chrono system_clock
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i)
        auto dummy = std::chrono::system_clock::now();
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("chrono::system_clock::now", start, end);

    // Test chrono steady_clock
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i)
        auto dummy = std::chrono::steady_clock::now();
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("chrono::steady_clock::now", start, end);

    // Test chrono high_resolution_clock
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i)
        auto dummy = std::chrono::high_resolution_clock::now();
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("chrono::high_resolution_clock::now", start, end);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我用 gcc7.2 -O3 编译时得到的输出:

clock_gettime: 24.484926 milliseconds
chrono::system_clock::now: 85.142108 milliseconds
chrono::steady_clock::now: 87.295347 milliseconds
chrono::high_resolution_clock::now: 84.437838 milliseconds
Run Code Online (Sandbox Code Playgroud)