¿Cómo se cronometra la ejecución de un programa java? No estoy seguro de qué clase debería usar para hacer esto.
Estoy 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);
final
tiene la ventaja de que no se le puede asignar accidentalmente (así como otras ventajas, como el acceso a clases anónimo, etc.). En este código no haría ninguna diferencia. Es una práctica bastante común hacer todofinal
y solofinal
unificarlo si es necesario.Tenga en cuenta que hay algunos problemas en los
System#nanoTime()
que no se puede usar de manera confiable en CPU de múltiples núcleos para registrar el tiempo transcurrido ... cada núcleo tiene su propio TSC ( Contador de marca de tiempo ): este contador se usa para obtener el tiempo nano (realmente es el número de ticks desde que arrancó la CPU).Por lo tanto, a menos que el sistema operativo realice alguna deformación temporal de TSC para mantener los núcleos sincronizados, si un hilo se programa en un núcleo cuando se toma la lectura de tiempo inicial y luego se cambia a un núcleo diferente, el tiempo relativo puede parecer que salta esporádicamente hacia atrás. y adelante.
Observé esto hace algún tiempo en AMD / Solaris, donde los tiempos transcurridos entre dos puntos de tiempo a veces regresaban como valores negativos o números positivos inesperadamente grandes. Había un parche del kernel de Solaris y una configuración de BIOS necesaria para forzar AMD PowerNow! apagado, que pareció resolverlo.
Además, hay (AFAIK) un error no solucionado hasta ahora cuando se usa Java
System#nanoTime()
en un entorno VirtualBox; causando todo tipo de extraños problemas de subprocesos intermitentes para nosotros, ya que gran parte deljava.util.concurrency
paquete depende del nano tiempo.Ver también:
¿System.nanoTime () es completamente inútil? http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html
fuente
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 }
Entonces ves cuánto tiempo tomó:
final long elapsedTimeMillis = System.currentTimeMillis() - startTime;
fuente
Puede hacer uso de
System#nanoTime()
. Consígalo antes y después de la ejecución y simplemente haga los cálculos. Se prefiere arribaSystem#currentTimeMillis()
porque tiene una mejor precisión. Dependiendo del hardware y la plataforma utilizada, es posible que obtenga 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 un perfilador .
fuente
nanoTime()
tiene un problema (al menos en Windows); la marca de tiempo es específica del núcleo del procesador. Tenía un programa que tenía un tiempo de ejecución negativo porque tenía la marca de tiempo de "inicio" en un núcleo y la marca de tiempo de "parada" en otro núcleo.Para cosas simples, System.currentTimeMillis () puede funcionar.
De hecho, es tan común que mi IDE esté configurado de modo que al ingresar "t0" me genere la siguiente línea:
final long t0 = System.currentTimeMillis()
Pero para cosas más complicadas, probablemente querrá usar medidas de tiempo estadísticas, como aquí (desplácese un poco hacia abajo y observe las medidas de tiempo expresadas, incluidas las desviaciones estándar, etc.):
http://perf4j.codehaus.org/devguide.html
fuente
Usando AOP / AspectJ y la
@Loggable
anotación de jcabi-aspectos puede hacerlo de manera fácil y compacta:@Loggable(Loggable.DEBUG) public String getSomeResult() { // return some value }
Cada llamada a este método se enviará a la instalación de registro SLF4J con
DEBUG
nivel de registro. Y cada mensaje de registro incluirá el tiempo de ejecución.fuente
Aquí hay algunas formas de encontrar el tiempo de ejecución en Java:
1) System.nanoTime ()
long startTime = System.nanoTime(); .....your code.... long endTime = System.nanoTime(); long totalTime = endTime - startTime; System.out.println("Execution time in nanoseconds : " + totalTime); System.out.println("Execution time in milliseconds : " + totalTime / 1000000);
2) System.currentTimeMillis ()
long startTime = System.currentTimeMillis(); .....your code.... long endTime = System.currentTimeMillis(); long totalTime = endTime - startTime; System.out.println("Execution time in milliseconds : " + totalTime);
3) Instant.now ()
long startTime = Instant.now().toEpochMilli(); .....your code.... long endTime = Instant.now().toEpochMilli(); long totalTime = endTime - startTime; System.out.println("Execution time in milliseconds: " + totalTime);
o
Instant start = Instant.now(); .....your code.... Instant end = Instant.now(); Duration interval = Duration.between(start, end); System.out.println("Execution time in seconds: " +interval.getSeconds());
4) Date.getTime ()
long startTime = new Date().getTime(); .....your code.... long endTime = new Date().getTime(); long totalTime = endTime - startTime; System.out.println("Execution time in milliseconds: " + totalTime);
fuente
usar mucho
startTime=System.currentTimeMillis()
para la hora de inicio, en la parte superior del cicloponer
long endTime= System.currentTimeMillis();
fuera del final del bucle. Tendrá que restar los valores para obtener el tiempo de ejecución en milisegundos.Si quiere tiempo en nanosegundos, consulte
System.nanoTime()
fuente
Creé una función de orden superior que toma el código que desea medir en / como una lambda:
class Utils { public static <T> T timeIt(String msg, Supplier<T> s) { long startTime = System.nanoTime(); T t = s.get(); long endTime = System.nanoTime(); System.out.println(msg + ": " + (endTime - startTime) + " ns"); return t; } public static void timeIt(String msg, Runnable r) { timeIt(msg, () -> {r.run(); return null; }); } }
Llámalo así:
Utils.timeIt("code 0", () -> System.out.println("Hallo") ); // in case you need the result of the lambda int i = Utils.timeIt("code 1", () -> 5 * 5 );
Salida:
Un agradecimiento especial a Andy Turner, quien me ayudó a reducir el despido. Vea aquí .
fuente
Échale un vistazo
System.currentTimeMillis()
.fuente
También puede probar Perf4J. Es una forma 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 durante un período 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]
fuente
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"); } }
fuente
Usar System.currentTimeMillis () es la forma correcta de hacer esto. Pero, si usa la línea de comando y desea cronometrar todo el programa de manera aproximada y rápida, piense en:
lo que le permite no modificar el código y el tiempo de su aplicación.
fuente