2008-12-15 20 views
199

En Java, ¿cuáles son las implicaciones de rendimiento y recursos de la utilización deSystem.currentTimeMillis (vs) new Date() vs. Calendar.getInstance(). GetTime()

System.currentTimeMillis() 

vs

new Date() 

vs

Calendar.getInstance().getTime() 

Como yo lo entiendo, System.currentTimeMillis() es el más eficiente. Sin embargo, en la mayoría de las aplicaciones, ese valor largo tendría que convertirse en una Fecha u otro objeto similar para hacer algo significativo para los humanos.

Respuesta

197

System.currentTimeMillis() es obviamente la más eficiente ya que ni siquiera crear un objeto, pero new Date() es realmente sólo un envoltorio delgada sobre una larga, por lo que no se queda atrás. Calendar, por otro lado, es relativamente lento y muy complejo, ya que tiene que lidiar con la considerable complejidad y todas las rarezas que son inherentes a las fechas y horas (años bisiestos, horario de verano, zonas horarias, etc.).

Es generalmente una buena idea para tratar sólo con marcas de tiempo largos o Date objetos dentro de su aplicación, y sólo usar Calendar cuando realmente se necesita realizar cálculos de fecha/hora, o para formatear fechas para mostrarlos al usuario. Si tiene que hacer mucho de esto, usar Joda Time es probablemente una buena idea, para una interfaz más limpia y un mejor rendimiento.

+1

¿Cuál es la diferencia entre timestamp y currentMillis? – pinkpanther

12

Yo prefiero usar el valor devuelto por System.currentTimeMillis() para todo tipo de cálculos y sólo utilizar CalendarDate o si necesito mostrar realmente un valor que es leído por los seres humanos. Esto también evitará el 99% de sus errores de horario de verano. :)

22

Si está usando una fecha, le recomiendo encarecidamente que utilice jodatime, http://joda-time.sourceforge.net/. El uso de System.currentTimeMillis() para los campos que son parece una muy mala idea porque terminará con un montón de código inútil.

Tanto la fecha como el calendario están muy trabajados, y Calendar definitivamente es el que tiene el peor rendimiento.

os aconsejo utilizar System.currentTimeMillis() cuando en realidad se está operando con milisegundos, por ejemplo a esto

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

Quería comentar sobre esto porque su ejemplo es exactamente una de las cosas que debería * NO * usar System.currentTimeMillis() for; no es una fuente de reloj monotónica, por lo que no puede calcular con fiabilidad el tiempo transcurrido con ella. Si el reloj del sistema se cambia mientras se está ejecutando el código que estás cronometrando, obtendrás resultados extraños (por ejemplo, negativos). En lugar de ello, use System.nanoTime(), que * es * monotónico * si * el sistema subyacente admite una fuente de reloj de este tipo (consulte http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6458294) – rem

+0

Sistema .currentTimeMillis no se ve afectado por la zona horaria. ¡Cambiar el tiempo del sistema afectará a System.nanotime de la misma manera que System.currentTimeMillis – Viktor

33

Mirando el JDK, el constructor más interna de Calendar.getInstance() tiene esto:

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

entonces ya hace automáticamente lo que sugieres. por defecto el constructor de la fecha ejerce en este:

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

Así que en realidad no se necesita para obtener la hora del sistema en concreto a menos que desee hacer algunos cálculos con él antes de la creación de su Calendario/objeto con él. También tengo que recomendar joda-time para utilizar como reemplazo de las clases de calendario/fecha de Java si su propósito es trabajar mucho con los cálculos de fecha.

+1

que el puntero al constructor de Date lo clavó! ¡Gracias! –

7

Dependiendo de su aplicación, puede que desee considerar usar System.nanoTime() en su lugar.

+0

Por qué, su pregunta era sobre recursos y rendimiento, nanoTime() usa más recursos – WolfmanDragon

+0

Lo mencioné porque es una opción que nadie más sugirió. El cartel no especificó una plataforma. La falla SDN 6876279 sugiere que currentTimeMillis() y nanoTime() toman casi lo mismo en algunas versiones de JDK. El póster tampoco especificó sus necesidades de precisión, por lo que la lista original puede ser inadecuada. – MykennaC

+4

Tarde como sea, todos los ejemplos en la pregunta tienen una noción absoluta de qué hora es, por ejemplo. 1,348,770,313,071 milis desde el inicio de la época de Unix. El tiempo que devuelve 'nanoTime' es relativo (generalmente al comienzo del programa) y sería una tontería si intentara convertirlo en una fecha. – Dunes

11

En mi máquina intenté comprobarlo. Mi resultado:

 
Calendar.getInstance().getTime() (*1000000 times) = 402ms 
new Date().getTime(); (*1000000 times) = 18ms 
System.currentTimeMillis() (*1000000 times) = 16ms 

No se olvide de GC (si se utiliza o Calendar.getInstance()new Date())

+1

preguntarse si habrá alguna diferencia si hay muchos hilos llame igual entre otros procesos – tgkprog

3

He intentado esto:

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

y el resultado fue:

Fecha() : 199

currentTimeMillis(): 3

+2

Este es un micro benchmark y debe tener cuidado de confiar en los resultados que obtiene. Eche un vistazo a http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java. – Axel

+1

Este punto de referencia no es significativo, o mejor, muestra que el sistema operativo en Java sí importa. Ejecuté el mismo punto de referencia en un bucle docenas de veces (moviendo la inicialización de "ahora" y "resultado" fuera del ciclo), y tuve lindas diferencias en cada ejecución: Fecha(): 322 a 330; currentTimeMillis(): 319 a 322. En algunas otras ejecuciones tuve Fecha(): 312 a 318; currentTimeMillis(): 324 a 335. Por lo tanto, en mi humilde opinión son bastante equivalentes, en casos reales (también mirando a la fuente de la fecha). JFYI, usé Java7 en Ubuntu. – Sampisa

0

System.currentTimeMillis() es obviamente el más rápido porque es solo una llamada a un método y no se necesita un recolector de basura.

+11

Su respuesta no tiene ningún valor, ya que es solo un subconjunto de la respuesta aprobada anteriormente. Debería intentar no responder de esta manera, especialmente sin considerar que es una pregunta muy antigua con una respuesta de calidad ya existente. –

+0

En segundo lugar, el recolector de basura no es necesario para objetos a corto plazo en el espacio de Eden de todos modos. –

Cuestiones relacionadas