System.currentTimeMillis()対new Date()対Calendar.getInstance()。getTime()


238

Javaでは、使用のパフォーマンスとリソースへの影響は何ですか

System.currentTimeMillis() 

new Date() 

Calendar.getInstance().getTime()

私が理解しているようにSystem.currentTimeMillis()、最も効率的です。ただし、ほとんどのアプリケーションでは、人間にとって意味のある処理を行うために、その長い値をDateなどのオブジェクトに変換する必要があります。

回答:


241

System.currentTimeMillis()オブジェクトを作成しないため、明らかに最も効率的new Date()ですが、実際には長いラッパーであり、それほど遅れていません。Calendar一方、日付と時刻に固有のかなりの複雑さとすべての奇妙さ(うるう年、夏時間、タイムゾーンなど)に対処する必要があるため、は比較的遅く、非常に複雑です。

一般に、Dateアプリケーション内の長いタイムスタンプまたはオブジェクトのみを処理し、Calendar実際に日付/時刻の計算を実行する必要がある場合、またはユーザーに表示するために日付をフォーマットする場合にのみ使用することをお勧めします。これをたくさん行う必要がある場合は、インターフェースをよりクリーンにしてパフォーマンスを向上させるために、Joda Timeを使用することをお勧めします。


2
タイムスタンプとcurrentMillisの違いは何ですか?
pinkpanther

1
@pinkpanther:「タイムスタンプ」は通常、「エポックスタート」からの秒数またはミリ秒数として解釈される時点を表す整数/長さを表すために使用されます。つまり、currentTimeMillis()はタイムスタンプを返します。
Michael Borgwardt、2018年

42

JDKを見ると、の最も内側のコンストラクタにCalendar.getInstance()は次のものが含まれています。

public GregorianCalendar(TimeZone zone, Locale aLocale) {
    super(zone, aLocale);
    gdate = (BaseCalendar.Date) gcal.newCalendarDate(zone);
    setTimeInMillis(System.currentTimeMillis());
}

そのため、あなたが提案したことはすでに自動的に行われています。日付のデフォルトのコンストラクタはこれを保持します:

public Date() {
    this(System.currentTimeMillis());
}

したがって、カレンダー/日付オブジェクトを作成する前にそれを使って計算したい場合を除いて、特にシステム時間を取得する必要はありません。また、日付計算を頻繁に処理することが目的である場合は、Java独自のカレンダー/日付クラスの代わりとして使用するjoda-timeを推奨する必要があります。


22

日付を使用する場合は、http: //joda-time.sourceforge.net/のjodatimeを使用することを強くお勧めします。使い方System.currentTimeMillis()のフィールドにしているあなたは役に立たない多くのコードになってしまいますので、非常に悪いアイデアのように日付音。

日付とカレンダーはどちらも深刻な問題を抱えており、カレンダーは間違いなくそれらすべての中で最悪のパフォーマーです。

System.currentTimeMillis()あなたが実際にミリ秒で操作しているときに使用することをお勧めします、例えばこのような

 long start = System.currentTimeMillis();
    .... do something ...
 long elapsed = System.currentTimeMillis() -start;

28
あなたの例はSystem.currentTimeMillis()を使用してはならないものの1つなので、これについてコメントしたいと思います。これは単調なクロックソースではないため、これを使用して経過時間を確実に計算することはできません。タイミングを設定しているコードの実行中にシステムクロックが変更されると、奇妙な(たとえば、負の)結果が得られます。代わりに、基になるシステムがそのようなクロックソースをサポートしている場合単調なSystem.nanoTime()を使用します(bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294を参照)
rem

System.currentTimeMillis自体はタイムゾーンの影響を受けません。システム時刻を変更すると、System.currentTimeMillisと同じようにSystem.nanotimeに影響します
Viktor

12

私はによって返された値使用して好むSystem.currentTimeMillis()すべての計算の種類と使用のみのためCalendarか、Date私は本当に人間によって読まれた値を表示する必要がある場合を。これにより、夏時間のバグの99%も防止されます。:)


12

私のマシンで確認してみました。私の結果:

Calendar.getInstance()。getTime()(* 1000000回)= 402ms
新しいDate()。getTime(); (* 1000000回)= 18ms
System.currentTimeMillis()(* 1000000回)= 16ms

GCを忘れないでください(Calendar.getInstance()またはを使用する場合new Date()


1
他の処理間で多くのスレッドが同じものを呼び出す場合、何か違いがあるのだろうか
tgkprog

7

アプリケーションによっては、System.nanoTime()代わりに使用を検討したい場合があります。


なぜ、彼の質問はリソースとパフォーマンスに関するものでした、nanoTime()はより多くのリソースを使用します
WolfmanDragon

他の誰も提案していないオプションであるため、私はそれを述べました。ポスターはプラットフォームを指定しませんでした。SDNバグ6876279は、一部のJDKバージョンでcurrentTimeMillis()とnanoTime()がほぼ同じになることを示唆しています。投稿者はまた、元のリストでは不十分である可能性がある正確性のニーズを指定していませんでした。
MykennaC 2010年

4
これが遅くなるかもしれませんが、問題のすべての例には、それが何時かという絶対的な概念があります。Unixエポックの開始から1,348,770,313,071ミリ秒。nanoTime戻る時間は(通常はプログラムの開始に対して)相対的であり、日付に変換しようとしても意味がありません。
砂丘2012

はい、ただしプログラムの開始時にcurrentTimeilliとnanoをいくつかの静的コードに格納し、それらをオフセットとして使用して、ダブルvar = currentTimeStart-nanoTimeStart + nanoTimeNowを使用してミリから正確なnanoを取得できます
tgkprog

3

私はこれを試しました:

        long now = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            new Date().getTime();
        }
        long result = System.currentTimeMillis() - now;

        System.out.println("Date(): " + result);

        now = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            System.currentTimeMillis();
        }
        result = System.currentTimeMillis() - now;

        System.out.println("currentTimeMillis(): " + result);

そして結果は:

日付():199

currentTimeMillis():3


4
これはマイクロベンチマークであり、得られる結果を信頼するように注意する必要があります。見ていstackoverflow.com/questions/504103/...を
アクセル

1
このベンチマークは重要ではない、またはより良い、それはJavaの下でオペレーティングシステムが重要であることを示しています。ループで同じベンチマークを数十回実行し( "now"と "result"の初期化をループの外に移動)、実行ごとにかなりの違いがありました:Date():322〜330; currentTimeMillis():319から322。他のいくつかの実行では、Date()は312から318でした。currentTimeMillis():324から335まで。実際のケースでは、IMHOはまったく同じです(日付のソースも確認します)。JFYI、私はUbuntuでJava7を使用しました。
サンピサ2016年

0

System.currentTimeMillis() メソッド呼び出しが1つだけであり、ガベージコレクターが必要ないため、明らかに最速です。


14
以前に承認された回答のサブセットにすぎないため、あなたの回答は価値がありません。この方法で回答しないようにしてください。特に、既存の質の高い回答では非常に古い質問であるとは考えないでください。
Nicklas Gnejs Eriksson 2014

1
第二に、とにかくエデン空間の短期オブジェクトにはガベージコレクターは必要ありません。
Niels Bech Nielsen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.