计算时间差,你的方式或许不是最佳实践!

来自:肥朝(微信号:feichao_java),作者:肥朝

我们计算两段代码时间差,很多同学公司的代码是采用以下这种方式。

long startTime = System.currentTimeMillis();
// 执行代码
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);

首先先说明,这种方式并不是不行。按照“能跑就行”的原则,这段代码,肯定是能用的!但是这并不是最佳实践,为何?

我们先来看一下JDK中的注释

/**
 * Returns the current time in milliseconds.  Note that
 * while the unit of time of the return value is a millisecond,
 * the granularity of the value depends on the underlying
 * operating system and may be larger.  For example, many
 * operating systems measure time in units of tens of
 * milliseconds.
 *
 * <p> See the description of the class <code>Date</code> for
 * a discussion of slight discrepancies that may arise between
 * "computer time" and coordinated universal time (UTC).
 *
 * @return  the difference, measured in milliseconds, between
 *          the current time and midnight, January 1, 1970 UTC.
 * @see     java.util.Date
 */

public static native long currentTimeMillis();

当然,毕竟有的同学英文能力有限,那肥朝就只能用之前介绍的文档神器来开门见山了


虽然文中的每个字都认识,但是这段话想表达的意思你可能还是不太清楚,有句话叫做,不怕现实,就怕对比。那么我们来看另外一种方式。

long startTime = System.nanoTime();
// 执行代码
long endTime = System.nanoTime();
System.out.println(endTime - startTime);

同样的,我们再来看看注释

/**
 * Returns the current value of the running Java Virtual Machine's
 * high-resolution time source, in nanoseconds.
 *
 * <p>This method can only be used to measure elapsed time and is
 * not related to any other notion of system or wall-clock time.
 * The value returned represents nanoseconds since some fixed but
 * arbitrary <i>origin</i> time (perhaps in the future, so values
 * may be negative).  The same origin is used by all invocations of
 * this method in an instance of a Java virtual machine; other
 * virtual machine instances are likely to use a different origin.
 *
 * <p>This method provides nanosecond precision, but not necessarily
 * nanosecond resolution (that is, how frequently the value changes)
 * - no guarantees are made except that the resolution is at least as
 * good as that of {@link #currentTimeMillis()}.
 *
 * <p>Differences in successive calls that span greater than
 * approximately 292 years (2<sup>63</sup> nanoseconds) will not
 * correctly compute elapsed time due to numerical overflow.
 *
 * <p>The values returned by this method become meaningful only when
 * the difference between two such values, obtained within the same
 * instance of a Java virtual machine, is computed.
 *
 * <p> For example, to measure how long some code takes to execute:
 *  <pre> {@code
 * long startTime = System.nanoTime();
 * // ... the code being measured ...
 * long estimatedTime = System.nanoTime() - startTime;}</pre>
 *
 * <p>To compare two nanoTime values
 *  <pre> {@code
 * long t0 = System.nanoTime();
 * ...
 * long t1 = System.nanoTime();}</pre>
 *
 * one should use {@code t1 - t0 < 0}, not {@code t1 < t0},
 * because of the possibility of numerical overflow.
 *
 * @return the current value of the running Java Virtual Machine's
 *         high-resolution time source, in nanoseconds
 * @since 1.5
 */

public static native long nanoTime();

此时我们再拿出神器:

从文中的描述加代码示例,告诉我们:

还是那句话,不怕现实,就怕对比。就算你完全不懂代码,根据小学的语文理解,都能看出在计算代码执行时间差上,选哪个方式,才是最佳实践。

最后,我们再看一下阿里巴巴开发手册给我们的建议:

你的公司代码是怎么计算时间差的,欢迎留言告诉肥朝。

推荐↓↓↓
Java编程
上一篇:我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration 下一篇:两道JVM面试题,竟让我回忆起了中学时代!