在日常開(kāi)發(fā)中,經(jīng)常會(huì)有計(jì)算方法調(diào)用時(shí)間的場(chǎng)景挑胸,我之前的做法一直是
long start =System.currentTimeMillis();
object.methodinvoke();
long end =System.currentTimeMillis();
long cost=end-start;//????
這里真的有個(gè)坑Q魍病!2绻蟆2就浮!=庠濉@铣洹!螟左!
來(lái)看看currentTimeMillis()這個(gè)方法的源碼注釋,這個(gè)方法返回的是當(dāng)前時(shí)間的微秒數(shù)啡浊。恰恰因?yàn)榉祷氐氖俏⒚霐?shù),而這個(gè)值的顆粒度取決于底層的操作系統(tǒng)胶背,所以就可能會(huì)很大巷嚣。例如,很多操作系統(tǒng)的時(shí)間顆粒度是10微妙钳吟。而且這個(gè)時(shí)間又可能受NTP影響而產(chǎn)生微調(diào)廷粒,從而導(dǎo)致時(shí)間很不準(zhǔn)確。
綜上,這種寫(xiě)法是不嚴(yán)謹(jǐn)?shù)摹?/p>
/**
* 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();
正確的操作應(yīng)該是這個(gè)樣子的:
long start =System.nanoTime();
object.methodinvoke();
long end =System.nanoTime();
long cost=end-start;// 為什么是準(zhǔn)確的呢坝茎?
來(lái)看看nanoTime()的源碼注釋涤姊,這個(gè)方法返回的是JVM運(yùn)行的納秒數(shù),它只依賴與當(dāng)前的jvm嗤放,并且不會(huì)出現(xiàn)同步的情況砂轻,所以是準(zhǔn)確的。
/**
* 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();
另外,在計(jì)算當(dāng)前日期的時(shí)候是要使用currentTimeMillis()的斤吐,因?yàn)樗窍鄬?duì)于 midnight, January 1, 1970 UTC的時(shí)間長(zhǎng)度,而nanoTime()是相對(duì)于jvm的運(yùn)行時(shí)間厨喂,這個(gè)時(shí)間是不確定的和措。