218

Javaでは、使用することでパフォーマンスとリソースにどのような影響がありますか

System.currentTimeMillis() 

new Date() 

Calendar.getInstance().getTime()

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

8 답변


219

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

一般的に、長いタイムスタンプだけを扱うことをお勧めします。Dateアプリケーション内のオブジェクトはCalendar実際に日付/時刻の計算を実行したり、ユーザーに表示するために日付をフォーマットしたりする必要があるとき。あなたがこれの多くをしなければならないならば、使用してジョダ時差よりきれいなインターフェースとより良いパフォーマンスのために、おそらく良い考えです。


  • タイムスタンプとcurrentMillisの違いは何ですか? - pinkpanther
  • @pinkpanther:"タイムスタンプ"通常、「エポック開始」からの秒数またはミリ秒数として解釈される時点を表す整数/ longを表すために使用されます。つまり、currentTimeMillis()はタイムスタンプを返します。 - Michael Borgwardt

38

JDKを見てください。Calendar.getInstance()これがあります:

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

だからそれはすでに自動的にあなたが提案したことをします。 Dateのデフォルトコンストラクタはこれを保持します。

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

したがって、Calendar / Dateオブジェクトを作成する前にそれを使用して計算しない限り、システム時間を取得する必要はありません。また私は推薦しなければならないヨウ素の時間あなたの目的が日付計算をたくさん扱うことであるならば、Java自身のカレンダー/日付クラスの代わりとして使うために。


  • Dateコンストラクタへのポインタがそれを釘付けにしました!ありがとうございます。 - Peter Perháč

22

あなたが日付を使っているならば、私はあなたがjodatimeを使うことを強く勧めます、http://joda-time.sourceforge.net/。を使うSystem.currentTimeMillis()その分野のためにあります日付は非常に悪い考えのように思えます。なぜなら、あなたは結局無駄なコードがたくさんあることになるからです。

日付とカレンダーの両方がひどく混乱しています、そしてカレンダーは間違いなくそれらすべての最も悪い実行者です。

私はあなたに使うように忠告しますSystem.currentTimeMillis()あなたが実際にミリ秒で操作している時、例えばこんな感じ

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


  • あなたの例はまさにあなたがすべきことの一つなので、私はこれについてコメントしたいと思いましたではないSystem.currentTimeMillis()を使用してください。単調なクロックソースではないので、それを使って確実に経過時間を計算することはできません。タイミングを合わせているコードが実行されている間にシステムクロックが変更されると、奇妙な(例えば否定的な)結果になります。代わりに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 times) = 402ms
new Date().getTime(); (*1000000 times) = 18ms
System.currentTimeMillis() (*1000000 times) = 16ms

GCを忘れないでください。Calendar.getInstance()またはnew Date()


  • 他の処理との間で多くのスレッドが同じ呼び出しをした場合、何らかの違いがあるのだろうか。 - tgkprog

7

アプリケーションによっては、使用を検討してください。System.nanoTime()代わりに。


  • なぜ、彼の質問はリソースとパフォーマンスに関するものでした、nanoTime()はより多くのリソースを使用します - WolfmanDragon
  • 他の誰からも提案されていないオプションなので、私はそれを述べました。ポスターはプラットフォームを指定していません。 SDNバグ6876279は、currentTimeMillis()とnanoTime()が一部のJDKバージョンでほぼ同じであることを示唆しています。ポスターはまた、その正確性の必要性を明記しておらず、そのためには元のリストは不適切であるかもしれない。 - MykennaC
  • これが遅れるかもしれないので、問題のすべての例はそれが例えば何時であるかの絶対的な概念を持っています。 Unixのエポックが始まってから1,348,770,313,071ミリ秒。その時nanoTime戻り値は相対的で(通常はプログラムの開始位置を基準としています)、日付に変換しようとすると意味がありません。 - Dunes
  • はい、ただし、プログラム起動時にcurrentTimeilliとnanoを静的コードに格納してから、それらをオフセットとして使用して、double var = currentTimeStart - nanoTimeStart + nanoTimeNowを使用してミリから正確なナノを取得できます。 - 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


  • これはマイクロベンチマークであり、得られた結果を信頼するように注意する必要があります。見てstackoverflow.com/questions/504103/…。 - Axel
  • このベンチマークは重要ではありません、またはそれ以上であれば、Java下のオペレーティングシステムが重要であることを示しています。同じベンチマークを何十回もループで実行し(「now」と「result」の初期化をループの外に移動)、実行ごとにかなりの違いがありました。Date():322 - 330; currentTimeMillis():319〜322。他のいくつかの実行では、Date():312〜318でした。 currentTimeMillis():324から335。それで、私見は実際のケースでは全く同等です(Dateのソースも見てください)。 JFYI、私はUbuntuでJava7を使いました。 - Sampisa

1

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


  • これは、以前に承認された回答の一部にすぎないため、回答には何の価値もありません。あなたはこの方法で答えないようにするべきです、特にそれがすでに存在する質の高い答えを持つ非常に古い質問であると考えないでください。 - Nicklas Gnejs Eriksson
  • 第二に、ガベージコレクタはとにかくエデン空間の短期間のオブジェクトには必要ありません。 - Niels Bech Nielsen

リンクされた質問


関連する質問

最近の質問