在Windows上,clock()
以毫秒为单位返回时间,但是在我正在处理的这个Linux机器上,它将它舍入到最接近的1000,因此精度仅为“第二”级而不是毫秒级别。
我使用QTime
类找到了Qt的解决方案,实例化一个对象并在其上调用start()
,然后调用elapsed()
来获取经过的毫秒数。
我有点幸运,因为我开始使用Qt,但我想要一个不依赖第三方库的解决方案,
有没有标准方法可以做到这一点?
更新
请不要推荐Boost ..
如果Boost和Qt可以做到这一点,那肯定不是魔术,必须有一些他们正在使用的标准!
答案 0 :(得分:137)
#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;
}
答案 1 :(得分:57)
请注意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
功能。
答案 2 :(得分:35)
您可以在方法的开头和结尾使用gettimeofday,然后区分两个返回结构。您将获得如下结构:
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
}
答案 3 :(得分:18)
我也推荐Boost提供的工具。无论是提到的Boost Timer,还是修改Boost.DateTime中的东西,或沙盒中都有新的建议库 - Boost.Chrono:最后一个将替换Timer并具有以下功能:
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 |结果。答案 4 :(得分:13)
我根据CTT's answer撰写了Timer
课程。它可以按以下方式使用:
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);
}
};
答案 5 :(得分:9)
如果您不需要将代码移植到旧的unices,则可以使用clock_gettime(),这将为您提供纳秒的时间(如果您的处理器支持该分辨率)。这是POSIX,但是从2001年开始。
答案 6 :(得分:4)
clock()经常是一个非常糟糕的分辨率。如果你想测量毫秒级的时间,可以选择使用clock_gettime(),explained in this question.
(请记住,您需要在Linux上与-lrt链接)。
答案 7 :(得分:3)
使用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
答案 8 :(得分:2)
clock()在linux上不返回毫秒或秒。通常,clock()在linux系统上返回微秒。解释clock()返回的值的正确方法是将它除以CLOCKS_PER_SEC以计算已经过了多长时间。
答案 9 :(得分:1)
在POSIX标准中,clock
的返回值是根据CLOCKS_PER_SEC符号定义的,实现可以任意方式自由定义。在Linux下,我对times()
函数运气不错。
答案 10 :(得分: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);
}
是的......跑两次并减去......
答案 11 :(得分:1)
gettimeofday - 问题是,如果更改硬件时钟,可能会有更低的值(例如使用NTP) 提升 - 不适用于此项目 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。
不要使用闹钟或ualarm功能,当你的过程努力工作时,你的精确度会很低。
答案 12 :(得分:0)
我更喜欢Boost Timer library的简单性,但是如果你不想使用第三方库,那么使用clock()似乎是合理的。
答案 13 :(得分: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的特定版本。
答案 14 :(得分:0)
我喜欢不使用gettimeofday()的Hola Soy方法。 它发生在我正在运行的服务器上,管理员更改了时区。时钟已更新,以显示相同(正确)的本地值。 这导致函数time()和gettimeofday()移动2小时,某些服务中的所有时间戳都被卡住了。
答案 15 :(得分: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
- 循环占用的总执行时间。这次包括操作系统由于多任务处理而切换进出main()
的执行上下文。