程序中经常用time()函数来返回当前系统时间的秒数,来计时或计算时间差。如果需要用到更高精度的时间,就会自然想到用clock()函数。想当然的认为它返回从程序开始tick数,用clock()/CLOCKS_PER_SEC就能得到以秒计数的时间了。然而结果不是这样,看下面的程序log。一行开头是系统时间,后面是clock()算出来的,明显比系统时间要慢不少。

2019-03-06 17:47:55.865 16213-18332/ E/jniUtil-jni: cur_time 3.399163
2019-03-06 17:47:56.273 16213-18332/ E/jniUtil-jni: cur_time 3.671865
2019-03-06 17:47:56.722 16213-18332/ E/jniUtil-jni: cur_time 4.006435
2019-03-06 17:47:57.113 16213-18332/ E/jniUtil-jni: cur_time 4.277441
2019-03-06 17:47:57.527 16213-18332/ E/jniUtil-jni: cur_time 4.540576
2019-03-06 17:47:57.928 16213-18332/ E/jniUtil-jni: cur_time 4.775973
2019-03-06 17:47:58.269 16213-18332/ E/jniUtil-jni: cur_time 4.925488
2019-03-06 17:47:58.394 16213-18332/ E/jniUtil-jni: cur_time 4.989181
2019-03-06 17:47:58.488 16213-18332/ E/jniUtil-jni: cur_time 5.023780
2019-03-06 17:47:58.911 16213-18332/ E/jniUtil-jni: cur_time 5.222049
2019-03-06 17:47:59.480 16213-18332/ E/jniUtil-jni: cur_time 5.476535
2019-03-06 17:47:59.980 16213-18332/ E/jniUtil-jni: cur_time 5.724581
2019-03-06 17:48:00.551 16213-18332/ E/jniUtil-jni: cur_time 5.995964
2019-03-06 17:48:00.965 16213-18332/ E/jniUtil-jni: cur_time 6.183607

原因是clock()计算的是从程序运行开始被程序进程使用的CPU时间tick,而不是真正现实世界流逝的时间。很显然这个时间肯定要比现实时间要慢的多,除非CPU只有你这么一个进程在跑,占用了全部CPU。所以如果你要benchmark一段代码,看看运行这段代码花费了多少时间,用clock()很合适。那么要比较精确地计算现实流逝地时间,怎么办呢?用clock_gettime()。

extern int clock_gettime(clockid_t, struct timespec*);

struct timespec {
__kernel_time_t tv_sec;
long tv_nsec;
};

第一个参数clockid_t类型常见的有四种:

CLOCK_REALTIME:系统实时时间。
CLOCK_MONOTONIC:从系统启动时开始计时,不受系统时间被用户改变的影响。
CLOCK_PROCESS_CPUTIME_ID:本进程到当前代码系统CPU花费的时间,包含该进程下的所有线程。
CLOCK_THREAD_CPUTIME_ID:本线程到当前代码系统CPU花费的时间。

可以看到,如果用CLOCK_PROCESS_CPUTIME_ID,就和直接用clock()是一样的。而要计算现实时间,就不能用后两种类型,必须用CLOCK_REALTIME或者CLOCK_MONOTONIC。要计算时间差,秒对秒一减,纳秒对纳秒一减,统一到同一个单位相加即可。

除了上面四种clockid_t类型,还有几种。

CLOCK_REALTIME_COARSE,CLOCK_MONOTONIC_COARSE:带COARSE后缀的,精度没有不带后缀的高,但是速度快。

CLOCK_MONOTONIC_RAW:和CLOCK_MONOTONIC类似,但是它是访问的硬件时间,不受NTP时间服务器的调整和adjtime()的影响。

CLOCK_BOOTTIME:和CLOCK_MONOTONIC一样,但是包含系统挂起的时间。

												

用clock()函数计时的坑的更多相关文章

  1. Clock函数用法

    clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t.在MSDN中,查得对clock函数定义如下: clock_t clock(void) ; 这个函数返回从“开启这个程序进程 ...

  2. clock函数返回负值~ (转)

    使用clock() 函数来进行计时,时不时的返回一个很大的负数,怎么检查也检查不出错误,现在找出错误原因,给大家分享一下. 来源网页:http://kebe-jea.blogbus.com/logs/ ...

  3. times、 time、clock函数说明

    sysconf( _SC_CLK_TCK )  功能  获取系统的 时钟滴答的频率. clock_gettime() clock()返回的是各个线程运行cpu时间的和, 返回值一直都是0. 定义函数: ...

  4. C 语言 clock() 函数,例:计算多项式值

    C 语言 clock() 函数,例:计算多项式值 /** * clock(): 捕捉从程序开始运行到 clock() 被调用时所耗费的时间. * 这个时间单位是 clock tick, 即" ...

  5. clock()函数的返回值精度问题

    clock()函数返回值为1毫秒,就是0.001秒.clock函数功 能: 返回处理器调用某个进程或函数所花费的时间.用 法: clock_t clock(void);说明:clock_t其实就是lo ...

  6. CUDA-F-2-2-核函数计时

    Abstract: 本文介绍CUDA核函数计时方法 Keywords: gettimeofday,nvprof 开篇废话 继续更新CUDA,同时概率和数学分析也在更新,欢迎大家访问www.face2a ...

  7. CUDA学习(二)之使用clock()函数

    clock()函数是C/C++中的计时函数,相关的数据类型是clock_t,使用clock函数可以计算运行某一段程序所需的时间,如下所示程序计算从10000000逐渐减一直到0所需的时间. #incl ...

  8. 不要在Lua中使用os.clock()函数

    1.os.clock函数的实现是调用了c语言的函数函数库,实现代码如下: static int os_clock (lua_State *L) { lua_pushnumber(L, ((lua_Nu ...

  9. C语言中clock函数的使用

    #include<cstdio> #include<cstdlib> #include<ctime> using namespace std; int main() ...

随机推荐

  1. docker for ubuntu 18 安装

    官网地址: https://docs.docker.com/install/linux/docker-ce/ubuntu/ docker的作用:解决不同机器之间的环境差异问题,方便迁移. 0. 卸载旧 ...

  2. 第三篇 Flask 中的 request

    第三篇 Flask 中的 request   每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前 ...

  3. linux服务开机自动启动

    zookeeper设置开机自动启动 第一种:直接修改/etc/rc.d/rc.local文件 在/etc/rc.d/rc.local文件中需要输入两行,其中export JAVA_HOME=/usr/ ...

  4. 解决time_wait过多

    需要真正找出问题或瓶颈,但调整单机参数能临时解决:(收集自:https://www.cnblogs.com/dadonggg/p/8778318.html) 编辑内核文件/etc/sysctl.con ...

  5. 重构现有代码:Refactoring

    重构现有代码:Refactoring 1.WHY SHOULD WE REFACTOR? 1.Refactoring Improves the Design of Software Without r ...

  6. odoo KeyError

    one2many字段对应的表名不存在造成

  7. 21-matlab 迷宫题

    dfs: 注意matlab里面的全局变量的使用 test.m: clc; clear; global A ii dx dy vis minpath path A=... [1 1 1 1 1 1 1 ...

  8. jq实现前端文件上传

    FormData FormData是XMLHttpRequest Level 2 新增的一个接口. 使用FormData可以实现各种文件上传. 使用 // 创建FormData的实例 var form ...

  9. pycrypto 安装 Crypto 报错 error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools

    error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools&quo ...

  10. 执行sql语句后报1055-- this is incompatible with sql_mode=only_full_group_by

    这个问题是mysql5.7中存在的问题,查看原因,在任意库执行select @@sql_mode,查到的结果为ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZER ...