在 Java 中测量时间
System.currentTimeMillis()
此方法返回当前距离 1970年1月1日(UTC,世界协调时)的毫秒值。虽然是返回的时间单位是毫秒,但是其返回的时间粒度取决于底层操作系统,可能会比毫秒要大。例如,许多操作系统以几十毫秒为单位来进行时间测量。
此处的时间颗粒度指的是此值多久改变一次。如果你在一个死循环中不断的打印此方法返回的毫秒值,有可能会发现打印的结果是不连续的。这就取决于底层操作系统的实现了。
对于不同的虚拟机实现,因为是基于物理时间,此方法也将会返回相同的结果。
使用 System.currentTimeMillis()
测试代码耗时:
long startTime = System.currentTimeMillis();
// ... the code being measured ...
long estimatedTime = System.currentTimeMillis() - startTime;
复制代码
System.nanoTime()
相较于 System.currentTimeMillis()
,这个方法返回的单位更精确:纳秒(0.001秒 = 1毫秒 = 100万纳秒)。此方法返回值一般仅用在测量耗时,因为其并不依赖于一个指定的时间点,而是一个随机的基准点。甚至这个基准的时间点有可能在未来,所以这个方法的返回值有可能是一个负的。但在同一个虚拟机中,这个随机的基准点至少是同一个。
此方法虽然返回的是纳秒,但是同 System.currentTimeMillis()
一样,此方法也是依赖于底层操作系统的实现,它可能并非每一个纳秒就会改变。但是能保证的是,其精度是要高于 System.currentTimeMillis()
的。
使用此方法时,注意此值可能溢出的情况。如果连续的时间大于 292 年的话,那么就可能会由于数字溢出导致无法正确测量时间。
使用 System.nanoTime()
测试代码耗时:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
复制代码
两种方法的区别
相较于 System.currentTimeMillis()
,System.nanoTime()
更加精确,但是它也更加重量级。System.currentTimeMillis()
方法在5、6个 CPU 时钟内即可返回结果,但是 System.nanoTime()
依赖于操作系统底层架构,可能需要需要100多个CPU时钟才能完成调用。
而且对于测量时间来说,System.nanoTime()
虽然返回的纳秒精度,但在大部分情况下,是不会精确到纳秒,很多时候使用还需要将其除以一些值。这使得其返回的低位部分意义不大。
在选择时,建议优先使用 System.currentTimeMillis()
,毕竟毫秒能满足大部分情况。
在 C 中测量时间
在 C 语言中测量时间最好的方法就是使用 <time.h>
头文件中的 clock()
方法:
clock_t begin = clock();
/* here, do your time-consuming job */
clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
复制代码
这个 clock()
的返回值虽然是一个 clock_t
类型,此值表示 CPU 的时钟数,将其除以 CLOCKS_PER_SEC
(定义在 <time.h>
里的宏)可以转换为秒。虽然其单位是秒,但是其精度是远远大于秒的,具体也是依赖于底层系统实现。因此,此值可以用使用浮点数来表示,以获得更高精度的时间值,就像代码里的那样。
这个方法是标准 C 中提供的,因此不用担心移植的问题。在 C 中也有其他的方式来获取时间:
<sys/time.h>
中的gettimeofday()
方法:C/C++获取时间方法:gettimeofday()<time.h>
中的clock_gettime()
方法:clock_gettime获取系统时间
这两种方式都可行,但是相比于 clock()
方法来说,还是稍显复杂。在使用时,clock()
基本足够。