25

のドキュメントにSystem.nanoTime()は次のように書かれています(私の強調)。

この方法は経過時間を測定するためにのみ使用でき、システムや実時間のその他の概念とは関係ありません。返される値は、固定されているが任意の時間からのナノ秒を表します(おそらく将来的には、値が負になる可能性があります)。この方法はナノ秒の精度を提供しますが、必ずしもナノ秒の精度である必要はありません。値が変更される頻度については保証されません。

私が見ているように、これは2つの異なる方法で解釈できます。

  1. 上記の太字の文は、個々の戻り値を示しています。次に、精度と精度を数値の意味で理解する必要があります。つまり、精度は有効桁数(切り捨ての位置)を指し、精度はその数値が正しいかどうかを示します( 「精度」と「精度」の違いは何ですか?

  2. 上記の太字の文は、メソッド自体の機能を示しています。次に、ダートボードのアナロジー(http://en.wikipedia.org/wiki/Precision_vs._accuracy#Accuracy_versus_precision:_the_target_analogy)に示されているように、精度と精度を理解する必要があります。したがって、低精度、高精度=>間違った値が高精度で繰り返しヒットされます。物理時間が静止していると想像すると、nanoTime()を連続して呼び出すと同じ数値が返されますが、実際の経過時間とは異なります。一定のオフセットによる基準時間。

正しい解釈はどれですか?私のポイントは、解釈2は、nanoTime()を使用した時間の測定(2つの戻り値を差し引くことによる)がナノ秒に正しいことを意味します(測定の一定のエラー/オフセットが排除されるため)が、解釈1は測定間のこの種のコンプライアンスを保証するものではないため、必ずしも時間差測定の高精度を意味するわけではありません。


2013年4月15日更新:のJava 7ドキュメントSystem.nanoTime()が更新され、以前の表現との混同の可能性に対処しました。

実行中のJava仮想マシンの高解像度タイムソースの現在の値をナノ秒単位で返します。

この方法は経過時間を測定するためにのみ使用でき、システムや実時間のその他の概念とは関係ありません。返される値は、固定されているが任意の起点時刻からのナノ秒を表します(おそらく将来的には、値が負になる可能性があります)。同じオリジンが、Java仮想マシンのインスタンスでのこのメソッドのすべての呼び出しで使用されます。他の仮想マシンインスタンスは、異なるオリジンを使用する可能性があります。

この方法はナノ秒の精度を提供しますが、必ずしもナノ秒の解像度(つまり、値が変化する頻度)ではありません。解像度が少なくとも。の解像度と同じである場合を除いて、保証は行われませんcurrentTimeMillis()

約292年(2 63ナノ秒)を超える連続した呼び出しの違いは、数値のオーバーフローのために経過時間を正しく計算しません。

このメソッドによって返される値は、Java仮想マシンの同じインスタンス内で取得された2つのそのような値の差が計算された場合にのみ意味があります。

4

4 に答える 4

12

Clojureコマンドラインで、次のようになります。

user=> (- (System/nanoTime) (System/nanoTime))
0
user=> (- (System/nanoTime) (System/nanoTime))
0
user=> (- (System/nanoTime) (System/nanoTime))
-641
user=> (- (System/nanoTime) (System/nanoTime))
0
user=> (- (System/nanoTime) (System/nanoTime))
-642
user=> (- (System/nanoTime) (System/nanoTime))
-641
user=> (- (System/nanoTime) (System/nanoTime))
-641

したがって、本質的には、その精度nanoTimeから直感的に期待できるものとは異なり、ナノ秒ごとに更新されるわけではありません。Windowsシステムでは、 内部でAPIを使用しています(この記事によると)。これにより、実際には約640 nsの解像度が得られるようです(私のシステムでは!)。QueryPerformanceCounter

絶対値は任意であるため、nanoTimeそれ自体では精度をまったく持たないことに注意してください。 連続する呼び出しの違いだけnanoTimeが意味を持ちます。その差の(不)正確さは、1マイクロ秒の球場にあります。

于 2012-07-12T13:56:36.123 に答える
10

最初の解釈は正しいです。ほとんどのシステムでは、最下位3桁は常にゼロになります。これは事実上マイクロ秒の精度を提供しますが、ナノ秒の固定精度レベルで報告します。

実際、もう一度見てみると、あなたの2番目の解釈も、何が起こっているのかについての有効な説明であり、おそらくもっとそうです。フリーズした時間を想像すると、レポートは常に同じ間違ったナノ秒数になりますが、マイクロ秒の整数として理解されれば正しいものになります。

于 2012-07-12T13:36:09.197 に答える
4

System.currentTimeMillis()&の違いの非常に興味深い機能の1つSystem.nanoTime()System.nanoTime()、壁掛け時計によって変化しないことです。時間のずれが大きいWindows仮想マシンでコードを実行します。System.currentTimeMillis()NTPがそのドリフトを修正するたびに、1〜2秒ずつ前後にジャンプする可能性があり、正確なタイムスタンプが無意味になります。(Windows 2003、2008 VPSエディション)

System.nanoTime()ただし、壁時計時刻の変更による影響を受けないため、NTPを介して取得した時間を取得し、NTPが最後にチェックされてからに基づいて修正を適用でき、壁時計の不利な状況System.nanoTime()よりもはるかに正確な時刻が得られます。System.currentTimeMillis()

これはもちろん直感に反しますが、知っておくと便利です

于 2013-09-12T09:30:52.730 に答える
2

私のような人が来て、この質問を何度も何度も読ん、それを理解しているのであれば、ここにもっと簡単な(私は願っています)説明があります。

Precision保持する桁数についてです。各々の:

long start = System.nanoTime();
long end   = System.nanoTime();

正確な数(多くの桁)になります。

は何かと比較してaccuracyのみ測定されるため、その値は非常に任意であり、測定できるものに依存しないため、への個々の呼び出しは意味がありません。精度を区別する唯一の方法は、2つの異なる呼び出しを行うことです。したがって、次のようになります。System.nanoTime

 long howMuch = end - start;

ナノ秒の精度にはなりません。実際、私のマシンでは、差は0.2〜0.3マイクロ秒です。

于 2018-02-15T20:34:21.113 に答える