我们发现毫秒级的精度不能满足我们的需求,因此我们引入了纳秒级的计时器。在Java平台上,计时代码唯一需要做出的改变就是调用System.nanoTime这个计时函数。为了检查纳秒级和毫秒级计时器之间是否存在某些关联,我们做了一些修改,代码如例A-9所示。
例A-9:在Java中使用纳秒级计时器
之前的表A-3是毫秒级的计时结果,表A-7所示的计时结果是纳秒级。我们可以看到最明显的差别就是标准方差收缩了一个数量级,因此能够更加准确地预测代码的期望执行时间。但是这个结果仍然存在精度上的问题——注意n=5 000 000时的标准方差。这个值看起来是一个奇异值。
因为我们相信使用纳秒级的计时器提供的帮助非常有限,所以我们仍然在算法相关章中使用毫秒级计时器来进行基准测试。我们也会对计时器进行修改,提供更精确的计时,避免出现重大的误差。而且,当我们希望跨平台比较执行时间时,UNIX系统上的纳秒级计时器还没有标准化,这也是我们采用毫秒级计时器的另外一个原因。
为什么同一份数据执行的时间不一致呢?让我们看看表A-3的数据,不同结果之间有15毫秒或16毫秒的波动。这些波动反映了Windows平台上Java计时器的精度问题,而不是我们的代码的问题。System.currentTimeMillis执行时会导致这些偏差值,但是只有在执行时间非常短时,这些值才会非常重要(例如,大约16毫秒)。
Sun Java工程师已经意识到了Windows平台上Java计时器的问题,但是现在没有解决这个问题的计划(这种状况已经存在6年)。相关信息可参见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4423429。