System.currentTimeMillis () vs. new Date () vs. Calendar.getInstance (). GetTime ()


239

In Java, quali sono le prestazioni e le implicazioni delle risorse dell'utilizzo

System.currentTimeMillis() 

vs.

new Date() 

vs.

Calendar.getInstance().getTime()

A quanto ho capito, System.currentTimeMillis()è il più efficiente. Tuttavia, nella maggior parte delle applicazioni, quel valore lungo dovrebbe essere convertito in una Data o in un oggetto simile per fare qualcosa di significativo per l'uomo.

Risposte:


242

System.currentTimeMillis()è ovviamente il più efficiente in quanto non crea nemmeno un oggetto, ma in new Date()realtà è solo un involucro sottile di un lungo, quindi non è molto indietro. Calendard'altra parte, è relativamente lento e molto complesso, poiché deve fare i conti con la considerevole complessità e tutte le stranezze inerenti a date e orari (anni bisestili, ora legale, fusi orari, ecc.).

In genere è una buona idea gestire solo timestamp o Dateoggetti lunghi all'interno dell'applicazione e utilizzarli solo Calendarquando è effettivamente necessario eseguire calcoli di data / ora o formattare le date per visualizzarle all'utente. Se devi fare molto di questo, usare Joda Time è probabilmente una buona idea, per un'interfaccia più pulita e prestazioni migliori.


2
Qual'è la differenza tra timestamp e currentMillis?
pinkpanther,

1
@pinkpanther: "timestamp" viene normalmente utilizzato per descrivere un numero intero / lungo che descrive un punto nel tempo quando interpretato come secondi o millisecondi da un "inizio di epoca". In altre parole, currentTimeMillis () restituisce un timestamp.
Michael Borgwardt,

43

Guardando il JDK, il costruttore più interno per Calendar.getInstance()questo ha questo:

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

quindi fa già automaticamente ciò che suggerisci. Il costruttore predefinito di Date contiene questo:

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

Quindi non c'è davvero bisogno di ottenere l'ora di sistema in modo specifico a meno che tu non voglia fare un po 'di matematica con esso prima di creare l'oggetto Calendar / Date con esso. Inoltre, devo consigliare joda-time da utilizzare in sostituzione delle proprie classi di calendario / data di Java se il vostro scopo è quello di lavorare molto con i calcoli della data.


22

Se stai USANDO una data, ti consiglio vivamente di usare jodatime, http://joda-time.sourceforge.net/ . Usando System.currentTimeMillis()per i campi che lo sono date sembra una pessima idea perché finirai con un sacco di codice inutile.

Sia la data che il calendario sono seriamente corretti e Calendar è sicuramente il peggior performer di tutti.

Ti consiglierei di usare System.currentTimeMillis()quando stai effettivamente operando con millisecondi, ad esempio in questo modo

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

28
Volevo commentare questo perché il tuo esempio è esattamente una delle cose per cui NON dovresti usare System.currentTimeMillis (); non è una sorgente di clock monotonica, quindi non è possibile calcolare in modo affidabile il tempo trascorso con esso. Se l'orologio di sistema viene modificato mentre è in esecuzione il codice che stai eseguendo, otterrai risultati strani (ad es. Negativi). Usa invece System.nanoTime (), che è monotonico se il sistema sottostante supporta tale sorgente di clock (vedi bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294 )
rem

System.currentTimeMillis stesso non è interessato dal fuso orario. La modifica dell'ora di sistema influirà su System.nanotime allo stesso modo di System.currentTimeMillis
Viktor

12

Preferisco utilizzare il valore restituito da System.currentTimeMillis()per tutti i tipi di calcoli e usare solo Calendaro Datese devo davvero visualizzare un valore letto dagli umani. Ciò eviterà anche il 99% dei bug dell'ora legale. :)


12

Sulla mia macchina ho provato a controllarlo. Il mio risultato:

Calendar.getInstance (). GetTime () (* 1000000 volte) = 402ms
nuova data (). getTime (); (* 1000000 volte) = 18ms
System.currentTimeMillis () (* 1000000 volte) = 16ms

Non dimenticare GC (se usi Calendar.getInstance()o new Date())


1
mi chiedo se ci sarà differenza se molti thread chiamano lo stesso tra altre elaborazioni
tgkprog

7

A seconda della tua applicazione, potresti considerare di utilizzare System.nanoTime()invece.


Perché, la sua domanda era su risorse e prestazioni, nanoTime () usa più risorse
WolfmanDragon

L'ho menzionato perché è un'opzione che nessun altro ha suggerito. Il poster non specificava una piattaforma. Il bug SDN 6876279 suggerisce che currentTimeMillis () e nanoTime () prendono lo stesso in alcune versioni di JDK. Il poster non specificava inoltre le loro esigenze di precisione, per le quali l'elenco originale potrebbe essere inadeguato.
MykennaC,

4
Per quanto tardi possa essere, tutti gli esempi nella domanda hanno una nozione assoluta di che ora è ad es. 1.348.770.313.071 millis dall'inizio dell'epoca di Unix. Il tempo che nanoTimeritorna è relativo (di solito all'inizio del programma) e sarebbe senza senso se si provasse a trasformarlo in una data.
Dune,

si ma potresti salvare currentTimeilli e nano in un codice statico all'avvio del programma, quindi usarli come offset per ottenere un nano accurato da milli usando un doppio var = currentTimeStart - nanoTimeStart + nanoTimeNow
tgkprog

3

Ho provato questo:

        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);

E il risultato è stato:

Data (): 199

currentTimeMillis (): 3


4
Questo è un micro benchmark e dovresti stare attento a fidarti dei risultati che ottieni. Dai un'occhiata a stackoverflow.com/questions/504103/… .
Axel,

1
Questo benchmark non è significativo, o meglio, mostra che il sistema operativo in Java è importante. Ho eseguito lo stesso benchmark in una sequenza dozzina di volte (spostando l'inizializzazione di "ora" e "risultato" fuori dal ciclo), e ho avuto differenze carine ad ogni corsa: Data (): da 322 a 330; currentTimeMillis (): da 319 a 322. Su alcune altre corse ho avuto Date (): da 312 a 318; currentTimeMillis (): da 324 a 335. Quindi, IMHO sono abbastanza equivalenti, su casi reali (anche guardando l'origine di Date). JFYI, ho usato Java7 su Ubuntu.
Sampisa,

0

System.currentTimeMillis() è ovviamente il più veloce perché è solo una chiamata di metodo e non è necessario il Garbage Collector.


14
La tua risposta non ha valore poiché è solo un sottoinsieme della risposta precedentemente approvata. Dovresti cercare di non rispondere in questo modo, soprattutto non considerando che è una domanda molto vecchia con una risposta di qualità già esistente.
Nicklas Gnejs Eriksson,

1
In secondo luogo, il garbage collector non è richiesto per gli oggetti a breve termine nello spazio Eden.
Niels Bech Nielsen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.