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

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

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

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

更新

请不要推荐Boost..

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

有帮助吗?

解决方案

您可以在开始和你的方法结束,然后差两个返回结构使用gettimeofday的。你会得到一个结构如下所示:

struct timeval {
  time_t tv_sec;
  suseconds_t tv_usec;
}

其他提示

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

请注意,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功能。

我还推荐 Boost 提供的工具。要么是提到的 Boost Timer,要么是从 Boost.DateTime 中破解一些东西,或者沙箱中有新的建议库 - Boost.Chrono: :最后一个将取代计时器,并将具有以下功能:

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

这是来源 功能列表的

我写了一个 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);
    }
};

如果你不需要的代码可以移植到旧的Unices,您可以使用clock_gettime(),它会给你的纳秒的时间的(如果您的处理器支持该决议)。这是POSIX,但是从2001年。

Clock() 的分辨率通常很差。如果您想测量毫秒级别的时间,一种替代方法是使用clock_gettime(),如下所示 在这个问题中进行了解释。

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

使用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

时钟()不在Linux返回毫秒或秒。通常时钟()在Linux系统返回微秒。解释由时钟(返回值)的适当的方法是通过CLOCKS_PER_SEC分才弄清楚多少时间已经过去了。

此应该工作...在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);
}

是啊...运行两次,并减去...

在POSIX标准clock具有在CLOCKS_PER_SEC符号来定义它的返回值和实现可以自由以任何方便的方式来定义此。在Linux下,我有好运气与times()功能。

gettimeofday的 - 问题是,如果你改变硬件时钟(与NTP例如),将可以具有较低的值 升压 - 不能用于此项目 时钟() - 通常返回一个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。

不要使用警报器ualarm功能,您将有精度低,当你的进程中取得的辛勤工作。

我更喜欢升压定时器库以它的简单,但如果你不想使用第三parrty库,利用时钟()似乎是合理的。

作为一个更新,似乎在windows时钟()测量挂钟时间(与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的特定版本。

我喜欢不使用的gettimeofday的HOLA大豆()的方法。 它发生在我正在运行的服务器管理员更改了时区上。时钟已更新,以显示相同的(正确的)本地值。 这引起了时间函数()和gettimeofday的()移位2小时,所有的时间标记在某些服务就卡住。

我使用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环溶于执行的总时间被跟踪。此时包含在操作系统进出main()的执行上下文由于多任务处理的切换。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top