轻松测量经过时间


297

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

我不明白的是为什么之前和之后的值相同?我了解这不是剖析我的程序的最佳方法,我只想了解花费多长时间。

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

doSomthing();
doSomthingLong();

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

我努力了:

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);

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

那大约**time taken = 4 45025是4秒25毫秒呢?


10
我不明白这个问题。当然,值是不同的。时间之间的间隔,因此time()返回一个不同的值。
汤玛斯(Thomas)

1
您是什么意思?“我不明白,为什么前后的值是不同的”?您正在获取当前时间(自1970年1月1日以来以秒为单位)time(NULL),第二次调用时将是第一次之后的N秒,因此...将有所不同(除非您正在执行的操作不会)请花一点时间完成...在这种情况下,它将与第一个相同)。
布赖恩·罗奇

1
您能否告诉我们打印的内容,以及使用秒表或挂钟(或日历)计时需要多长时间?
马特·柯蒂斯

4
抱歉,我的意思是两个值都相同。我打错了我的问题。
hap497 2010年

Answers:


333
//***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;

10
是的,这应该是答案
Ferenc Dajka

23
要运行它,您必须添加#include <chrono>指令,并且我将报告时间更改为:(std::cout << "Time difference (sec) = " << (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) /1000000.0 <<std::endl;并且在编译时不要忘记C ++ 11标志:-std=c++11
Antonello

1
顺便说一句,这测量的是CPU时间,而不是挂钟时间。对?
Nikos

4
@ RestlessC0bra根据cppreference上的文档,“此时钟与挂钟时间无关(例如,它可能是自上次重启以来的时间),并且最适合用于测量间隔。”
cylus

1
这是什么数据类型?std :: chrono :: duration_cast <std :: chrono ::
microseconds

272
#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;
}

time()功能仅在一秒内准确,但在一秒内有CLOCKS_PER_SEC“时钟”。即使过分简化,这也是一种易于携带的测量方式。


129
请注意,这只是clock()测量CPU时间,而不是实际经过的时间(可能更长)。
jlstrecker 2013年

12
在为集群编程并行代码时,此方法无法反映实际时间...
Nicholas Hamilton

3
这似乎是最简单的方法。您是否愿意更新或解决@jlstrecker发表的评论?
罗拉·阿特金斯

5
出于多种原因,以上发布的解决方案不是一个好的解决方案。这是正确的答案- stackoverflow.com/questions/2962785/...
Xofo

1
我尝试了这种解决方案,并且正如评论所建议的,我的计时器比实际时间快得多。
RTbecard

267

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

感谢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;
}

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;

对客户最有用的

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


完整的代码可以在这里找到。我记录基于chrono 构建基准测试工具的尝试。


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

invoke(forward<decltype(func)>(func), forward<Args>(args)...);

提供作为成员函数指针的可调用对象。


2
不错 我的代码中有类似的东西,但是使用了与该类不同的接口:我在构造函数中有一个code_timer采用开始时间(std::chrono::system_clock::now();)的类(),该方法code_timer::ellapsed用于衡量新now()调用与构造函数中的调用之间的差异,以及code_timer::reset将开始时间重置为新now()结果的方法。为了衡量代码中函子的执行情况,我在类外使用了一个免费函数。这样就可以测量从构造对象到发出紧急呼叫所需的时间。
utnapistim 2014年

7
<nitpick>:在chrono必须这样做之前(请避免使用.count()),请不要离开系统。让客户端.count()在被迫致电时打电话(例如,对于I / O,这确实是不幸的)。客户可能希望在I / O(例如平均)之前对一堆持续时间进行后处理,而这最好在chrono系统内完成。
Howard Hinnant 2015年

1
@ user3241228 1. VS2013不支持自动返回类型(仅尾随返回类型-这是c ++ 14功能尚不可用)。2.我相信是原因,但我问aq只是为了确定
Nikos Athanasiou 2015年

2
为什么不std::forward<F>(func)呢?
oliora '16

3
@oliora是同一回事。我更喜欢,std::forward<decltype(func)>(func)因为它可以应用于不存在语法的泛型lambdas(auto&& func)的参数,F并且很容易在#define fw(arg) std::forward<decltype(arg)>(arg)我在基准库中所做的实用程序宏中进行抽象(因此,这是一种语法,在此不再赘述)答案)
Nikos Athanasiou'2

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 );

4
这总是给我整数秒。那应该发生吗?
硝酸钠

10
时间永远只会返回秒,因此不能用于亚秒级测量。
DeepDeadpool

31

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

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

long int before = GetTickCount();

// Perform time-consuming operation

long int after = GetTickCount();

7
我在Linux上使用它。所以我不能使用GetTickCount()函数。
hap497 2010年

1
已经不介意;)感谢您更新帖子的标签
RvdK 2010年

它可以工作并给出实时时间,而不是CPU时间。我测试了它放置SleepEx(5000,0)在适当位置的//执行耗时的操作和的差异after以及before几乎5秒。
Ruchir 2015年

14

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

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

printf ("time = %d secs\n", t1 - t0);

使用可以获得更好的结果getttimeofday(),它以秒为单位返回当前时间,以毫秒为单位返回当前时间time()


13

time(NULL)函数将返回自1970年1月1日00:00开始经过的秒数。并且因为该函数在程序中的不同时间被调用,所以在C ++中它总是不同的 时间。


我不知道为什么有人反对,但是您的答案并不完全正确。对于初学者来说,它不会返回日期时间,并且不会总是不同的。
马特·乔纳

12
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)

用法如下:

{
    PROFILE_BLOCK("Some time");
    // your code or function
}

在范围上类似于RAII

注意这不是我的,但我认为这与这里有关


1
包括失踪
Stepan Yakovenko

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 

3
尽管您的回答令人赞赏,但我们确实希望使用前言,其中包含对代码的简短描述。谢谢。
2012年

2
这不是经过时间,而是处理器时间。
JonnyJD 2014年


8
#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;
}

4

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()

尽管POSIX clock_gettime(CLOCK_MONOTONIC, &time)应该与POSIX 相同,steady_clock::now()但是它快了x3倍!

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

#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;
}

这是我用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

3

time(NULL)函数调用将返回自epoc:1970年1月1日以来经过的秒数。也许您想要做的是取两个时间戳之间的差:

size_t start = time(NULL);
doSomthing();
doSomthingLong();

printf ("**MyProgram::time elapsed= %lds\n", time(NULL) - start);

3

正如其他人已经指出的那样,C标准库中的time()函数的分辨率不超过一秒。可能提供更好分辨率的唯一完全可移植的C函数似乎是clock(),但它测量的是处理器时间而不是挂钟时间。如果满足于将自己限制在POSIX平台(例如Linux)上,那么clock_gettime()函数是一个不错的选择。

从C ++ 11开始,有许多更好的计时功能可提供更好的分辨率,其格式应可在不同的编译器和操作系统之间移植。同样,boost :: datetime库提供了很好的高分辨率定时类,这些类应该具有很高的可移植性。

使用这些工具中的任何一个的挑战是查询系统时钟所引入的时间延迟。通过使用clock_gettime(),boost :: datetime和std :: chrono进行试验,此延迟很容易就只有几微秒。因此,在测量代码任何部分的持续时间时,您需要允许存在大约此大小的测量误差,或者尝试以某种方式纠正该零误差。理想情况下,您可能希望对函数所花费的时间进行多次测量,并计算多次运行所花费的平均时间或最大/最小时间。

为了帮助解决所有这些可移植性和统计信息收集问题,我一直在开发Github上可用的cxx-rtimers库,该库试图为C ++代码的计时块,计算零错误以及报告来自多个嵌入式计时器的统计信息提供简单的API。在您的代码中。如果您有C ++ 11编译器,则只需#include <rtimers/cxx11.hpp>使用以下代码即可:

void expensiveFunction() {
    static rtimers::cxx11::DefaultTimer timer("expensiveFunc");
    auto scopedStartStop = timer.scopedStart();
    // Do something costly...
}

在程序退出时,您将获得写入std :: cerr的计时状态摘要,例如:

Timer(expensiveFunc): <t> = 6.65289us, std = 3.91685us, 3.842us <= t <= 63.257us (n=731)

其中显示了平均时间,其标准偏差,上限和下限以及调用此函数的次数。

如果您想使用Linux专用的计时功能,则可以#include <rtimers/posix.hpp>,或者如果您拥有Boost库,但是使用的是较旧的C ++编译器,则可以#include <rtimers/boost.hpp>。这些计时器类的版本也可以从多个线程中收集统计计时信息。还有一些方法可以让您估计与两个立即连续查询系统时钟有关的零误差。


2

在内部该函数将访问系统的时钟,这就是为什么每次调用它都会返回不同的值。通常,对于非函数语言,函数中可能有许多副作用和隐藏状态,仅通过查看函数的名称和参数就无法看到它们。


2

从中可以看出,tv_sec分别存储了经过的秒数,而tv_usec分别存储了经过的微秒。他们不是彼此的转换。因此,必须将它们更改为适当的单位并添加以获得经过的总时间。

struct timeval startTV, endTV;

gettimeofday(&startTV, NULL); 

doSomething();
doSomethingLong();

gettimeofday(&endTV, NULL); 

printf("**time taken in microseconds = %ld\n",
    (endTV.tv_sec * 1e6 + endTV.tv_usec - (startTV.tv_sec * 1e6 + startTV.tv_usec))
    );

2

在linux上,clock_gettime()是不错的选择之一。您必须链接实时库(-lrt)。

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

#define BILLION  1000000000L;

int main( int argc, char **argv )
  {
    struct timespec start, stop;
    double accum;

    if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }

    system( argv[1] );

    if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }

    accum = ( stop.tv_sec - start.tv_sec )
          + ( stop.tv_nsec - start.tv_nsec )
            / BILLION;
    printf( "%lf\n", accum );
    return( EXIT_SUCCESS );
  }

2

我需要测量库中各个函数的执行时间。我不想用时间测量功能包装每个函数的每个调用,因为它很丑陋并加深了调用堆栈。我也不想将计时器代码放在每个函数的顶部和底部,因为例如当该函数可以提前退出或引发异常时,它会使情况一团糟。因此,我最终要做的是制作一个计时器,该计时器使用自己的寿命来测量时间。

通过这种方式,我可以通过仅在相关代码块(功能或任何作用域)的开头实例化这些对象之一,然后允许实例析构函数测量自实例超出范围时进行构造。您可以在此处找到完整的示例但是该结构非常简单:

template <typename clock_t = std::chrono::steady_clock>
struct scoped_timer {
  using duration_t = typename clock_t::duration;
  const std::function<void(const duration_t&)> callback;
  const std::chrono::time_point<clock_t> start;

  scoped_timer(const std::function<void(const duration_t&)>& finished_callback) :
      callback(finished_callback), start(clock_t::now()) { }
  scoped_timer(std::function<void(const duration_t&)>&& finished_callback) :
      callback(finished_callback), start(clock_t::now()) { }
  ~scoped_timer() { callback(clock_t::now() - start); }
};

当超出范围时,该结构将在提供的函子上回调您,以便您可以对计时信息进行某些操作(打印或存储它或进行其他操作)。如果你需要做一些更复杂的,你甚至可以使用std::bind具有std::placeholders更多的参数回调函数。

这是一个使用它的简单示例:

void test(bool should_throw) {
  scoped_timer<> t([](const scoped_timer<>::duration_t& elapsed) {
    auto e = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(elapsed).count();
    std::cout << "took " << e << "ms" << std::endl;
  });

  std::this_thread::sleep_for(std::chrono::seconds(1));

  if (should_throw)
    throw nullptr;

  std::this_thread::sleep_for(std::chrono::seconds(1));
}

如果您想更刻意,还可以使用newdelete显式启动和停止计时器,而无需依靠作用域来完成。


1

它们是相同的,因为doSomething函数的执行速度比计时器的粒度快。尝试:

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

for(i = 0; i < 1000; ++i) {
    doSomthing();
    doSomthingLong();
}

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

1

这两个值相同的原因是,您的长过程不会花费那么长的时间-少于一秒。您可以尝试在函数的末尾添加一个长循环(for(int i = 0; i <100000000; i ++);)以确保这是问题所在,然后我们可以从那里开始...

如果上述情况确实成立,您将需要找到其他系统功能(我了解您在linux上工作,所以我不能用功能名称来帮助您)以更准确地测量时间。我确定在Linux中有一个类似于GetTickCount()的函数,您只需要找到它即可。


1

我通常使用以下内容:

#include <chrono>
#include <type_traits>

using perf_clock = std::conditional<
    std::chrono::high_resolution_clock::is_steady,
    std::chrono::high_resolution_clock,
    std::chrono::steady_clock
>::type;

using floating_seconds = std::chrono::duration<double>;

template<class F, class... Args>
floating_seconds run_test(Func&& func, Args&&... args)
{
   const auto t0 = perf_clock::now();
   std::forward<Func>(func)(std::forward<Args>(args)...);
   return floating_seconds(perf_clock::now() - t0);
} 

它与@ nikos-athanasiou所建议的相同,只是我避免使用非稳定时钟,并使用浮动秒数作为持续时间。


1
在此typeswitch上:通常high_resolution_clocksystem_clock或的typedef steady_clock。因此要跟踪,std::conditional如果该is_steady部分为真,则选择,high_resolution_clock它是的(一个typedef)steady_clock。如果为假,则steady_clock再次选择。只是steady_clock从一开始就使用...
Nikos Athanasiou

@ nikos-athanasiou我完全同意5gon12eder的评论,即标准不要求“典型”情况,因此某些STL可能以其他方式实现。我希望我的代码更加通用,并且与实现细节无关。
oliora

它不是必需的,但在20.12.7.3中有明确说明:high_resolution_clock may be a synonym for system_clock or steady_clock。原因是:high_resolution_clock代表时钟周期最短的时钟,因此无论执行哪种方式,它都有两种选择,即稳定与否。无论我们做出什么选择,都说实现与其他两个时钟不同,这就像说我们有一个更好的实现是选择不使用的稳定(或不稳定)时钟(对于稳定或不稳定的时钟)。知道如何好,知道为什么更好
Nikos Athanasiou

@ nikos-athanasiou我更希望100%安全,特别是当这没有运行时开销和不可检测的编译时间开销时。如果需要,可以依赖“可能”和升空。
oliora

au相反,我的朋友,是您依靠“ may”,但适合自己。如果您想百分百确定并继续编写,那么对于您和您的代码用户,还应该找到一种方法,避免将不同时钟的时间点混为一谈(如果这种类型的开关具有某种意义,在不同平台上的行为会有所不同)。玩得开心!
Nikos Athanasiou

0

回答OP的三个特定问题。

“我不明白的是,为什么前后的值相同?

一个问题和示例代码显示time()分辨率为1秒,因此答案必须是两个函数在不到1秒的时间内执行。但是有时,如果两个计时器标记跨越一秒的边界,它将(显然不合逻辑)通知1秒

下一个示例使用gettimeofday()填充此结构

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};

第二个问题问:“我怎么看的结果**time taken = 0 26339是否意味着26339纳秒= 26.3毫秒?”

我的第二个答案是花费的时间是0秒和26339微秒,即0.026339秒,这证明了第一个示例在不到1秒的时间内执行。

第三个问题问:“关于什么的**time taken = 4 45025,这是否意味着4秒钟,然后25毫秒?”

我的第三个答案是花费的时间是4秒和45025微秒,即4.045025秒,这表明OP改变了他先前计时的两个功能所执行的任务。


0
#include <ctime>
#include <functional>

using namespace std;

void f() {
  clock_t begin = clock();

  // ...code to measure time...

  clock_t end = clock();

  function<double(double, double)> convtime = [](clock_t begin, clock_t end)
  {
     return double(end - begin) / CLOCKS_PER_SEC;
  };

  printf("Elapsed time: %.2g sec\n", convtime(begin, end));

}

与此处可用的示例相似,仅具有附加转换功能+打印输出。


0

我创建了一个可自动测量经过时间的类,请检查此链接中的代码(c ++ 11):https : //github.com/sonnt174/Common/blob/master/time_measure.h

如何使用类TimeMeasure的示例:

void test_time_measure(std::vector<int> arr) {
  TimeMeasure<chrono::microseconds> time_mea;  // create time measure obj
  std::sort(begin(arr), end(arr));
}

我喜欢你的单位印刷声明。将代码移植到gcc和clang需要什么?(wandbox.org
霍华德·

1
@HowardHinnant:感谢您的发言,我也更新了gcc和clang的代码。
Sirn Nguyen Truong

0

Matlab 加香!

tic启动秒表计时器以衡量效果。该函数记录tic命令执行时的内部时间。用该toc功能显示经过的时间。

#include <iostream>
#include <ctime>
#include <thread>
using namespace std;

clock_t START_TIMER;

clock_t tic()
{
    return START_TIMER = clock();
}

void toc(clock_t start = START_TIMER)
{
    cout
        << "Elapsed time: "
        << (clock() - start) / (double)CLOCKS_PER_SEC << "s"
        << endl;
}

int main()
{
    tic();
    this_thread::sleep_for(2s);
    toc();

    return 0;
}

-4

您可以使用SFML库,它是简单快速的多媒体库。它包括许多有用且定义明确的类,例如Clock,Socket,Sound,Graphics等。它非常易于使用,强烈建议使用。

这是这个问题的一个例子。

sf::Clock clock;
...
Time time1 = clock.getElapsedTime();
...
Time time2 = clock.restart();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.