2010-04-03 9 views
64

Disculpe si esto suena como una pregunta tonta, pero ¿cómo se sincroniza la ejecución de un programa java? No estoy seguro de qué clase debería usar para hacer esto.Cómo sincronizar la velocidad de ejecución del programa Java

Estoy un poco buscando algo como:

//Some timer starts here 
for (int i = 0; i < length; i++) { 
    // Do something 
} 
//End timer here 

System.out.println("Total execution time: " + totalExecutionTime); 

Gracias

Respuesta

106
final long startTime = System.currentTimeMillis(); 
for (int i = 0; i < length; i++) { 
    // Do something 
} 
final long endTime = System.currentTimeMillis(); 

System.out.println("Total execution time: " + (endTime - startTime)); 

Espero que esto ayudó.

+1

realmente debería ser nanoTime en realidad – Eugene

+4

No debería ser nanoTime. Ver la respuesta de rhu. – fabspro

+3

¿Hay alguna razón particular por la que utilizó "final" aquí? ¿Qué sería diferente si abandonara esa palabra clave? – dijxtra

7

Usted puede hacer uso de System#nanoTime(). Obténgalo antes y después de la ejecución y solo haga los cálculos. Se prefiere arriba de System#currentTimeMillis() porque tiene una mejor precisión. Dependiendo del hardware y la plataforma utilizada, de lo contrario puede obtener un espacio incorrecto en el tiempo transcurrido. Aquí, con Core2Duo en Windows, entre aproximadamente 0 y ~ 15 ms, en realidad no se puede calcular nada.

Una herramienta más avanzada es profiler.

+0

El temporizador en Windows no tiene una resolución especialmente buena por defecto. * Hay * un temporizador de alto rendimiento también, pero es mucho más difícil de usar incluso desde C y Java no (AFAIK) proporciona acceso a ese bajo nivel de hackeo sin un truco JNI. –

+0

+1 para el enlace del perfilador. –

+1

'nanoTime()' tiene un problema (al menos en Windows); la marca de tiempo es específica del núcleo del procesador. Tuve un programa que obtuvo un tiempo de ejecución negativo porque obtuvo la marca de tiempo "inicio" en un núcleo y la marca de tiempo "detener" en otro núcleo. – gustafc

6

Usted obtiene la hora actual del sistema, en milisegundos:

final long startTime = System.currentTimeMillis(); 

Entonces haces lo que vas a hacer:

for (int i = 0; i < length; i++) { 
    // Do something 
} 

A continuación, ver el tiempo que tomó:

final long elapsedTimeMillis = System.currentTimeMillis() - startTime; 
+0

La respuesta de BalusC también es correcta; depende de la resolución del temporizador necesaria y de por qué necesita el tiempo. –

1

uso a largo startTime=System.currentTimeMillis() para la hora de inicio, en la parte superior del bucle

poner long endTime= System.currentTimeMillis(); fuera de la final del bucle. Deberá restar los valores para obtener el tiempo de ejecución en milisegundos.

Si quieres que el tiempo en nanosegundos, echa un vistazo a System.nanoTime()

0
public class someClass 
{ 
    public static void main(String[] args) // your app start point 
    { 
     long start = java.util.Calendar.getInstance().getTimeInMillis(); 

     ... your stuff ... 

     long end = java.util.Calendar.getInstance().getTimeInMillis(); 
     System.out.println("it took this long to complete this stuff: " + (end - start) + "ms"); 
    } 
} 
29

Tenga en cuenta que hay algunas cuestiones en las System#nanoTime() no se puede utilizar de forma fiable en la CPU de varios núcleos para registrar el tiempo transcurrido ... cada núcleo tiene mantiene su propio TSC (Time Stamp Counter): este contador se usa para obtener el tiempo nano (realmente es el número de tics desde que arrancó la CPU). Por lo tanto, a menos que el sistema operativo realice un ciclo de tiempo TSC para mantener los núcleos sincronizados, entonces si se programa un hilo en un núcleo cuando se toma la lectura inicial, luego se cambia a un núcleo diferente, el tiempo relativo puede esporádicamente parece saltar hacia adelante y hacia atrás.

Observé esto hace algún tiempo en AMD/Solaris, donde los tiempos transcurridos entre dos puntos de temporización a veces regresaban como valores negativos o como números positivos inesperadamente grandes. ¡Había un parche de kernel de Solaris y una configuración de BIOS necesaria para forzar AMD PowerNow! apagado, que pareció resolverlo.

Además, hay (AFAIK) un error tan-lejos no fijada utilizando java System#nanoTime() en un entorno VirtualBox; causando todo tipo de problemas de subprocesamiento intermitentes extraños para nosotros, ya que gran parte del paquete java.util.concurrency se basa en nano time.

Consulte también:

Is System.nanoTime() completely useless? http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html

+3

+1 para una explicación clara de las deficiencias de nanoTime. – Jason

3

Para cosas simples, System.currentTimeMillis() puede trabajar.

De hecho, es tan común que mi IDE está configurado de manera que al entrar en "t0" me genera la siguiente línea:

final long t0 = System.currentTimeMillis() 

Pero para cosas más complicadas, probablemente querrá usar mediciones de tiempo estadísticos , como aquí (desplácese hacia abajo un poco y mirar las mediciones de tiempo expresado incluyendo desviaciones estándar etc.):

http://perf4j.codehaus.org/devguide.html

+0

+1 para señalar el código del generador automático. Uso una declaración similar todo el tiempo y no sabía cómo insertar plantillas de código. ¡Solo descubrí cómo hacer eso con Eclipse, y definitivamente ayudará! – Jason

+0

Todos los servicios de Codehaus han finalizado. Tu enlace ahora está roto. – naXa

0

también puede tratar Perf4J. Es una manera ordenada de hacer lo que está buscando, y ayuda en las estadísticas de rendimiento agregadas como media, mínima, máxima, desviación estándar y transacciones por segundo en un lapso de tiempo establecido. Un extracto de http://perf4j.codehaus.org/devguide.html:

StopWatch stopWatch = new LoggingStopWatch(); 

try { 
    // the code block being timed - this is just a dummy example 
    long sleepTime = (long)(Math.random() * 1000L); 
    Thread.sleep(sleepTime); 
    if (sleepTime > 500L) { 
     throw new Exception("Throwing exception"); 
    } 

    stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms"); 
} catch (Exception e) { 
    stopWatch.stop("codeBlock2.failure", "Exception was: " + e); 
} 

Salida:

INFO: start[1230493236109] time[447] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493236719] time[567] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception] 
INFO: start[1230493237286] time[986] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception] 
INFO: start[1230493238273] time[194] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493238467] time[463] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493238930] time[310] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493239241] time[610] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception] 
INFO: start[1230493239852] time[84] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493239937] time[30] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493239968] time[852] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception] 
0

Usando System.currentTimeMillis() es la forma correcta de hacerlo. Sin embargo, si se utiliza la línea de comandos, y desea medir el tiempo de todo el programa, aproximadamente, y de forma rápida, piense:

time java App 

que le permite no modificar el código y la hora de su aplicación.

+0

Esto depende de cómo ejecute el código. Si se trata de una pieza de código que ejecuta un servidor, entonces incluirá el tiempo de inicio que es incorrecto. –

2

El uso de AOP/AspectJ y @Loggable anotación de jcabi-aspects que pueden hacer que sea fácil y compacto:

@Loggable(Loggable.DEBUG) 
public String getSomeResult() { 
    // return some value 
} 

Cada llamada a este método será enviado a las instalaciones de registro SLF4J con DEBUG nivel de registro. Y cada mensaje de registro incluirá el tiempo de ejecución.

Cuestiones relacionadas