102

在 Windows 上,clock()以毫秒为单位返回时间,但在我正在处理的这个 Linux 机器上,它将它四舍五入到最接近的 1000,因此精度仅为“秒”级别,而不是毫秒级别。

我找到了使用QTime该类的 Qt 解决方案,实例化一个对象并调用start()它,然后调用elapsed()以获取经过的毫秒数。

我很幸运,因为我开始使用 Qt,但我想要一个不依赖第三方库的解决方案,

没有标准的方法可以做到这一点吗?

更新

请不要推荐Boost ..

如果 Boost 和 Qt 可以做到这一点,那肯定不是魔法,他们必须使用某种标准!

4

16 回答 16

138
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    struct timeval start, end;

    long mtime, seconds, useconds;    

    gettimeofday(&start, NULL);
    usleep(2000);
    gettimeofday(&end, NULL);

    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;

    mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;

    printf("Elapsed time: %ld milliseconds\n", mtime);

    return 0;
}
于 2009-02-25T23:20:24.050 回答
59

请注意,clock不测量挂钟时间这意味着如果您的程序需要 5 秒,clock则不一定要测量 5 秒,但可以更多(您的程序可以运行多个线程,因此可能比实时消耗更多的 CPU)或更少。它测量所用CPU 时间的近似值。要查看差异,请考虑此代码

#include <iostream>
#include <ctime>
#include <unistd.h>

int main() {
    std::clock_t a = std::clock();
    sleep(5); // sleep 5s
    std::clock_t b = std::clock();

    std::cout << "difference: " << (b - a) << std::endl;
    return 0;
}

它在我的系统上输出

$ difference: 0

因为我们所做的只是睡觉而不使用任何 CPU 时间!但是,使用gettimeofday我们得到我们想要的(?)

#include <iostream>
#include <ctime>
#include <unistd.h>
#include <sys/time.h>

int main() {
    timeval a;
    timeval b;

    gettimeofday(&a, 0);
    sleep(5); // sleep 5s
    gettimeofday(&b, 0);

    std::cout << "difference: " << (b.tv_sec - a.tv_sec) << std::endl;
    return 0;
}

我的系统上的输出

$ difference: 5

如果您需要更高的精度但又想获得CPU 时间,那么您可以考虑使用该getrusage功能。

于 2009-03-15T10:33:44.380 回答
37

您可以在方法的开头和结尾使用 gettimeofday,然后区分两个返回结构。您将获得如下结构:

struct timeval {
  time_t tv_sec;
  suseconds_t tv_usec;
}

编辑:正如下面的两条评论所建议的,clock_gettime(CLOCK_MONOTONIC) 是一个更好的选择,如果你有可用的,现在应该几乎无处不在。

编辑:其他人评论说您也可以将现代 C++ 与 std::chrono::high_resolution_clock 一起使用,但这不能保证是单调的。改为使用 stable_clock。

于 2009-02-25T23:12:25.143 回答
18

我还推荐 Boost 提供的工具。提到的 Boost Timer,或者从 Boost.DateTime 中破解一些东西,或者沙箱中有新的提议库 - Boost.Chrono:最后一个将替代 Timer,并将具有:

  • C++0x 标准库的时间实用程序,包括:
    • 类模板duration
    • 类模板time_point
    • 时钟:
      • system_clock
      • monotonic_clock
      • high_resolution_clock
  • 类模板timer,带有 typedef:
    • system_timer
    • monotonic_timer
    • high_resolution_timer
  • 处理时钟和定时器:
    • process_clock,捕获实际、用户 CPU 和系统 CPU 时间。
    • process_timer,捕获经过的实际时间、用户 CPU 时间和系统 CPU 时间。
    • run_timer,|process_timer| 的方便报告 结果。
  • C++0x 标准库的编译时有理算术。

这是功能列表的来源

于 2009-02-25T23:33:34.487 回答
13

我已经Timer根据CTT 的回答编写了一个课程。它可以通过以下方式使用:

Timer timer = Timer();
timer.start();
/* perform task */
double duration = timer.stop();
timer.printTime(duration);

这是它的实现:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
using namespace std;

class Timer {
private:

    timeval startTime;

public:

    void start(){
        gettimeofday(&startTime, NULL);
    }

    double stop(){
        timeval endTime;
        long seconds, useconds;
        double duration;

        gettimeofday(&endTime, NULL);

        seconds  = endTime.tv_sec  - startTime.tv_sec;
        useconds = endTime.tv_usec - startTime.tv_usec;

        duration = seconds + useconds/1000000.0;

        return duration;
    }

    static void printTime(double duration){
        printf("%5.6f seconds\n", duration);
    }
};
于 2010-09-09T14:55:49.663 回答
9

如果您不需要将代码移植到旧的 unice,您可以使用 clock_gettime(),它会给您以纳秒为单位的时间(如果您的处理器支持该分辨率)。它是 POSIX,但从 2001 年开始。

于 2009-02-26T03:17:26.663 回答
4

clock() 的分辨率通常很差。如果您想以毫秒级别测量时间,一种替代方法是使用 clock_gettime(),如本问题所述。

(请记住,您需要在 Linux 上使用 -lrt 链接)。

于 2009-03-15T07:32:59.307 回答
4

使用 C++11,std::chrono::high_resolution_clock您可以这样做:

#include <iostream>
#include <chrono>
#include <thread>
typedef std::chrono::high_resolution_clock Clock;

int main()
{
    std::chrono::milliseconds three_milliseconds{3};

    auto t1 = Clock::now();
    std::this_thread::sleep_for(three_milliseconds);
    auto t2 = Clock::now();

    std::cout << "Delta t2-t1: " 
              << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count()
              << " milliseconds" << std::endl;
}

输出:

Delta t2-t1: 3 milliseconds

演示链接:http ://cpp.sh/2zdtu

于 2016-06-07T08:21:25.047 回答
2

clock() 在 Linux 上不返回毫秒或秒。通常 clock() 在 linux 系统上返回微秒。解释 clock() 返回的值的正确方法是将其除以 CLOCKS_PER_SEC 以确定已经过去了多少时间。

于 2009-02-25T23:07:12.537 回答
1

在 POSIX 标准clock中,它的返回值是根据 CLOCKS_PER_SEC 符号定义的,并且实现可以以任何方便的方式自由定义它。在Linux下,我对这个功能很幸运times()

于 2009-02-25T23:08:47.977 回答
1

这应该工作......在Mac上测试......

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

int main() {
        struct timeval tv;
        struct timezone tz;
        struct tm *tm;
        gettimeofday(&tv,&tz);
        tm=localtime(&tv.tv_sec);
        printf("StartTime: %d:%02d:%02d %d \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
}

是的...运行两次并减去...

于 2009-02-25T23:18:51.010 回答
1

gettimeofday - 问题是,如果你改变硬件时钟(例如使用 NTP) B​​oost - 不适用于此项目 clock() - 通常返回一个 4 字节整数,这意味着它的容量低,并且一段时间后它返回负数。

我更喜欢创建自己的类并每 10 毫秒更新一次,所以这种方式更灵活,我什至可以改进它以拥有订阅者。

class MyAlarm {
static int64_t tiempo;
static bool running;
public:
static int64_t getTime() {return tiempo;};
static void callback( int sig){
    if(running){
        tiempo+=10L;
    }
}
static void run(){ running = true;}
};

int64_t MyAlarm::tiempo = 0L;
bool MyAlarm::running = false;

刷新它我使用setitimer:

int main(){
struct sigaction sa; 
struct itimerval timer; 

MyAlarm::run();
memset (&sa, 0, sizeof (sa)); 
sa.sa_handler = &MyAlarm::callback; 

sigaction (SIGALRM, &sa, NULL); 


timer.it_value.tv_sec = 0; 
timer.it_value.tv_usec = 10000; 



timer.it_interval.tv_sec = 0; 
timer.it_interval.tv_usec = 10000; 


setitimer (ITIMER_REAL, &timer, NULL); 
.....

查看 setitimer 以及 ITIMER_VIRTUAL 和 ITIMER_REAL。

不要使用警报或报警功能,当您的过程辛苦工作时,您的精度会很低。

于 2012-09-04T12:25:45.917 回答
0

我更喜欢Boost Timer 库,因为它简单,但如果您不想使用第三方库,使用 clock() 似乎是合理的。

于 2009-02-25T23:18:35.490 回答
0

作为更新,似乎在 windows clock() 上测量挂钟时间(具有 CLOCKS_PER_SEC 精度)

 http://msdn.microsoft.com/en-us/library/4e2ess30(VS.71).aspx

在 Linux 上,它测量当前进程使用的内核之间的 cpu 时间

http://www.manpagez.com/man/3/clock

并且(看起来,正如原始海报所指出的那样)实际上比 CLOCKS_PER_SEC 的精度低,尽管这可能取决于 Linux 的特定版本。

于 2010-08-11T14:29:40.603 回答
0

我喜欢不使用 gettimeofday() 的 Hola Soy 方法。它发生在我正在运行的服务器上,管理员更改了时区。时钟已更新以显示相同(正确)的本地值。这导致函数 time() 和 gettimeofday() 偏移 2 小时,并且某些服务中的所有时间戳都卡住了。

于 2014-10-09T12:27:33.527 回答
0

C++timeb.

#include <sys/timeb.h>
class msTimer 
{
public:
    msTimer();
    void restart();
    float elapsedMs();
private:
    timeb t_start;
};

成员函数:

msTimer::msTimer() 
{ 
    restart(); 
}

void msTimer::restart() 
{ 
    ftime(&t_start); 
}

float msTimer::elapsedMs() 
{
    timeb t_now;
    ftime(&t_now);
    return (float)(t_now.time - t_start.time) * 1000.0f +
           (float)(t_now.millitm - t_start.millitm);
}

使用示例:

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char** argv) 
{
    msTimer t;
    for (int i = 0; i < 5000000; i++)
        ;
    std::cout << t.elapsedMs() << endl;
    return 0;
}

我电脑上的输出是“19”。类的精度为msTimer毫秒级。for在上面的使用示例中,跟踪了 -loop占用的总执行时间。这一次包括操作系统main()因多任务处理而切换进出执行上下文。

于 2016-01-23T04:04:28.030 回答