用clock()函数计时的坑
程序中经常用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一样,但是包含系统挂起的时间。
推荐阅读
-
Excel用OFFSET与MATCH函数查找图片并根据姓名显示员工的照片
-
用TEXT函数解决日期用&连接字符日期变成数字格式的问题
-
那些年用httpclient时踩过的一些坑
-
用Excel Sumif函数做查询模板统计客户在不同时间借款的总金额
-
用VLOOKUP函数根据编号查找日期结果却显示为数字的解决方法
-
用实例详解Python中的Django框架中prefetch_related()函数对数据库查询的优化
-
用map函数来完成Python并行任务的简单示例
-
CSS3 函数技巧 用css 实现js实现的事情(clac Counters Tooltip)
-
我用ASP写的m行n列的函数,动态输出创建TABLE行列
-
详解关于微信setData回调函数中的坑