17

Java は、現在の時刻を取得するための 2 つのメソッドへのアクセスを提供します:System.nanoTime()System.currentTimeMillis(). 最初のものはナノ秒単位で結果を返しますが、実際の精度はそれよりもはるかに悪いです (数マイクロ秒)。

JVM は、特定のマシンごとに可能な限り最高の価値をすでに提供していますか? それ以外の場合、特定のシステムに関連付けられている可能性があるため、より詳細な測定を行うことができる Java ライブラリはありますか?

4

5 に答える 5

19

超正確な時間測定値を取得する際の問題は、一部のプロセッサがそのような小さな増分を提供できない/提供できないことです。

私の知る限り、System.currentTimeMillis()そしてSystem.nanoTime()あなたが見つけることができる最高の測定値です。

どちらも値を返すことに注意してくださいlong

于 2009-09-30T22:19:48.370 に答える
6

Java で時間をナノ秒スケールまで測定するのは少し無意味です。時折の GC ヒットは、これが与えた可能性のあるあらゆる種類の精度を簡単に一掃します。いずれにせよ、ドキュメントには、ナノ秒の精度が得られますが、ナノ秒の精度と同じではないと記載されています。また、どのような場合でもナノ秒を報告しないオペレーティング システムがあります (これが、アクセス時に 1000 に量子化された回答を見つける理由です。これは運ではなく、制限です)。

それだけでなく、機能が OS によって実際にどのように実装されているかによっては、量子化された結果が得られる場合があります (たとえば、中間値ではなく、常に 64 または 128 で終わる回答)。

このメソッドの目的は、ある (近い) 開始時刻と現在との 2 つの時差を見つけることであることも注目に値します。実行時間の長いアプリケーションの開始時に System.nanoTime() を取得し、その後に System.nanoTime() を取得すると、リアルタイムからかなり離れている可能性があります。したがって、実際には 1 秒未満の期間にのみ使用する必要があります。それよりも長い実行時間が必要な場合は、ミリ秒で十分です。(そうでない場合は、最後の数を補ってください。おそらくクライアントに感銘を与え、結果も同様に有効です。)

于 2009-09-30T22:38:45.297 に答える
1

残念ながら、現時点では Java RTS が十分に成熟しているとは思いません。

Java 時間は最高の価値を提供しようとします (実際には、ネイティブ コードに委譲してカーネル時間を取得します)。ただし、JVM 仕様では、主に GC アクティビティや基盤となるシステムのサポートなどについて、この粗い時間測定の免責事項を作成しています。

  • 同時 GC を実行している場合でも、特定の GC アクティビティがすべてのスレッドをブロックします。
  • デフォルトの Linux クロック ティックの精度はわずか 10 ミリ秒です。Linuxカーネルがサポートしていない場合、Javaはそれを改善することはできません.

アプリで GC を実行する必要がない場合を除き、#1 に対処する方法がわかりません。まともな中サイズのアプリケーションは、GC の一時停止におそらく数十ミリ秒かかることがあります。精度要件が 10 ミリ秒未満の場合は、おそらく不運です。

#2に関しては、Linuxカーネルを調整してより正確にすることができます。ただし、カーネルコンテキストの切り替えがより頻繁に行われるようになったため、すぐに使える量も少なくなります。

おそらく、私たちはそれを別の角度から見る必要があります。OPS が 10ms 未満の精度を必要とする理由はありますか? Ops に精度が 10 ミリ秒であることを伝え、その時点での GC ログも確認して、その時間に GC アクティビティがなくても、時刻が +-10 ミリ秒の精度であることを確認してもよろしいですか?

于 2009-09-30T22:38:22.677 に答える
0

ナノ秒のオーダーである種の現象を記録しようとしている場合、本当に必要なのはリアルタイム オペレーティング システムです。タイマーの精度は、オペレーティング システムの高解像度タイマーの実装と基盤となるハードウェアに大きく依存します。

ただし、利用可能な RTOS バージョンがあるため、引き続き Java を使用できます。

于 2009-09-30T22:39:38.180 に答える