計算時間差,調(diào)用System的nanoTime()還是currentTimeMillis()

在日常開發(fā)中,經(jīng)常會有計算方法調(diào)用時間的場景,我之前的做法一直是

long start =System.currentTimeMillis();
object.methodinvoke();
long end =System.currentTimeMillis();
long cost=end-start;//????

這里真的有個坑!?。。。。。。?!

來看看currentTimeMillis()這個方法的源碼注釋,這個方法返回的是當(dāng)前時間的微秒數(shù)。恰恰因為返回的是微秒數(shù),而這個值的顆粒度取決于底層的操作系統(tǒng),所以就可能會很大。例如,很多操作系統(tǒng)的時間顆粒度是10微妙。而且這個時間又可能受NTP影響而產(chǎn)生微調(diào),從而導(dǎo)致時間很不準(zhǔn)確。
綜上,這種寫法是不嚴(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)該是這個樣子的:

long start =System.nanoTime();
object.methodinvoke();
long end =System.nanoTime();
long cost=end-start;// 為什么是準(zhǔn)確的呢?

來看看nanoTime()的源碼注釋,這個方法返回的是JVM運行的納秒數(shù),它只依賴與當(dāng)前的jvm,并且不會出現(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();

另外,在計算當(dāng)前日期的時候是要使用currentTimeMillis()的,因為它是相對于 midnight, January 1, 1970 UTC的時間長度,而nanoTime()是相對于jvm的運行時間,這個時間是不確定的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容