Question Comment chronométrer l'exécution d'une méthode en Java?


Comment puis-je obtenir le temps d'exécution d'une méthode? Existe-t-il une classe d'utilitaire Timer pour des choses comme le temps nécessaire à une tâche, etc?

La plupart des recherches sur Google renvoient des résultats pour les minuteurs qui programment les tâches et les tâches, ce qui n'est pas ce que je veux.


661
2017-10-07 20:10


origine


Réponses:


Il y a toujours la manière démodée:

long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();

long duration = (endTime - startTime);  //divide by 1000000 to get milliseconds.

954
2017-10-07 20:16



Je vais avec la réponse simple. Travaille pour moi.

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

System.out.println("That took " + (endTime - startTime) + " milliseconds");

Cela fonctionne plutôt bien. La résolution est évidemment seulement à la milliseconde, vous pouvez faire mieux avec System.nanoTime (). Il y a quelques limitations à la fois (tranches de programme du système d'exploitation, etc.) mais cela fonctionne plutôt bien.

Moyenne sur un couple de courses (le plus sera le mieux) et vous aurez une bonne idée.


160
2017-10-07 20:14



Allez les gars! Personne n'a mentionné le Goyave façon de le faire (ce qui est sans doute génial):

import com.google.common.base.Stopwatch;

Stopwatch timer = Stopwatch.createStarted();
//method invocation
LOG.info("Method took: " + timer.stop());

La bonne chose est que Stopwatch.toString () fait un bon travail de sélection des unités de temps pour la mesure. C'est à dire. si la valeur est petite, elle va sortir 38 ns, si elle est longue, elle montrera 5m 3s

Encore plus agréable:

Stopwatch timer = Stopwatch.createUnstarted();
for (...) {
   timer.start();
   methodToTrackTimeFor();
   timer.stop();
   methodNotToTrackTimeFor();
}
LOG.info("Method took: " + timer);

Remarque: Google Guava nécessite Java 1.6+


142
2018-03-13 20:11



En utilisant Instant et Durée de la nouvelle API de Java 8,

Instant start = Instant.now();
Thread.sleep(5000);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

les sorties,

PT5S

95
2018-02-02 09:19



Utilisez un profileur (JProfiler, Netbeans Profiler, Visual VM, Eclipse Profiler, etc.). Vous obtiendrez les résultats les plus précis et est le moins intrusif. Ils utilisent le mécanisme JVM intégré pour le profilage qui peut également vous fournir des informations supplémentaires telles que les traces de pile, les chemins d'exécution et des résultats plus complets si nécessaire.

Lorsque vous utilisez un profileur entièrement intégré, il est trivial de profiler une méthode. Clic droit, Profiler -> Ajouter aux méthodes racines. Ensuite, exécutez le profileur comme si vous étiez en train de faire un test ou un débogueur.


77
2017-10-07 21:35



Rassemblé tous les moyens possibles en un seul endroit.

Rendez-vous amoureux

Date startDate = Calendar.getInstance().getTime();
long d_StartTime = new Date().getTime();
Thread.sleep(1000 * 4);
Date endDate = Calendar.getInstance().getTime();
long d_endTime = new Date().getTime();
System.out.format("StartDate : %s, EndDate : %s \n", startDate, endDate);
System.out.format("Milli = %s, ( D_Start : %s, D_End : %s ) \n", (d_endTime - d_StartTime),d_StartTime, d_endTime);

Système.currentTimeMillis ()

long startTime = System.currentTimeMillis();
Thread.sleep(1000 * 4);
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime);  
System.out.format("Milli = %s, ( S_Start : %s, S_End : %s ) \n", duration, startTime, endTime );
System.out.println("Human-Readable format : "+millisToShortDHMS( duration ) );

Lisible par l'homme Format

public static String millisToShortDHMS(long duration) {
    String res = "";    // java.util.concurrent.TimeUnit;
    long days       = TimeUnit.MILLISECONDS.toDays(duration);
    long hours      = TimeUnit.MILLISECONDS.toHours(duration) -
                      TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
    long minutes    = TimeUnit.MILLISECONDS.toMinutes(duration) -
                      TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
    long seconds    = TimeUnit.MILLISECONDS.toSeconds(duration) -
                      TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
    long millis     = TimeUnit.MILLISECONDS.toMillis(duration) - 
                      TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration));

    if (days == 0)      res = String.format("%02d:%02d:%02d.%04d", hours, minutes, seconds, millis);
    else                res = String.format("%dd %02d:%02d:%02d.%04d", days, hours, minutes, seconds, millis);
    return res;
}

Goyave: Google  ChronomètrePOT «Un but de Stopwatch est de mesurer le temps écoulé en nanosecondes.

com.google.common.base.Stopwatch g_SW = Stopwatch.createUnstarted();
g_SW.start();
Thread.sleep(1000 * 4);
g_SW.stop();
System.out.println("Google StopWatch  : "+g_SW);

Apache Commons LangPOT  « Chronomètre fournit une API pratique pour les horaires.

org.apache.commons.lang3.time.StopWatch sw = new StopWatch();
sw.start();     
Thread.sleep(1000 * 4);     
sw.stop();
System.out.println("Apache StopWatch  : "+ millisToShortDHMS(sw.getTime()) );

JODA-TEMPS

public static void jodaTime() throws InterruptedException, ParseException{
    java.text.SimpleDateFormat ms_SDF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
    String start = ms_SDF.format( new Date() ); // java.util.Date

    Thread.sleep(10000);

    String end = ms_SDF.format( new Date() );       
    System.out.println("Start:"+start+"\t Stop:"+end);

    Date date_1 = ms_SDF.parse(start);
    Date date_2 = ms_SDF.parse(end);        
    Interval interval = new org.joda.time.Interval( date_1.getTime(), date_2.getTime() );
    Period period = interval.toPeriod(); //org.joda.time.Period

    System.out.format("%dY/%dM/%dD, %02d:%02d:%02d.%04d \n", 
        period.getYears(), period.getMonths(), period.getDays(),
        period.getHours(), period.getMinutes(), period.getSeconds(), period.getMillis());
}

API de date Java de Java 8 " UNE Durée objet représente une période de temps entre deux Instant objets.

Instant start = java.time.Instant.now();
    Thread.sleep(1000);
Instant end = java.time.Instant.now();
Duration between = java.time.Duration.between(start, end);
System.out.println( between ); // PT1.001S
System.out.format("%dD, %02d:%02d:%02d.%04d \n", between.toDays(),
        between.toHours(), between.toMinutes(), between.getSeconds(), between.toMillis()); // 0D, 00:00:01.1001 

Cadre de printemps fournit Chronomètre classe d'utilité pour mesurer le temps écoulé en Java.

StopWatch sw = new org.springframework.util.StopWatch();
sw.start("Method-1"); // Start a named task
    Thread.sleep(500);
sw.stop();

sw.start("Method-2");
    Thread.sleep(300);
sw.stop();

sw.start("Method-3");
    Thread.sleep(200);
sw.stop();

System.out.println("Total time in milliseconds for all tasks :\n"+sw.getTotalTimeMillis());
System.out.println("Table describing all tasks performed :\n"+sw.prettyPrint());

System.out.format("Time taken by the last task : [%s]:[%d]", 
        sw.getLastTaskName(),sw.getLastTaskTimeMillis());

System.out.println("\n Array of the data for tasks performed « Task Name: Time Taken");
TaskInfo[] listofTasks = sw.getTaskInfo();
for (TaskInfo task : listofTasks) {
    System.out.format("[%s]:[%d]\n", 
            task.getTaskName(), task.getTimeMillis());
}

Sortie:

Total time in milliseconds for all tasks :
999
Table describing all tasks performed :
StopWatch '': running time (millis) = 999
-----------------------------------------
ms     %     Task name
-----------------------------------------
00500  050%  Method-1
00299  030%  Method-2
00200  020%  Method-3

Time taken by the last task : [Method-3]:[200]
 Array of the data for tasks performed « Task Name: Time Taken
[Method-1]:[500]
[Method-2]:[299]
[Method-3]:[200]

51
2017-12-04 10:43



Ce n'est probablement pas ce que vous vouliez que je dise, mais c'est un bon usage de l'AOP. Fouettez un intercepteur proxy autour de votre méthode, et faites le timing là-dedans.

Le quoi, le pourquoi et le comment de l'AOP dépassent malheureusement la portée de cette réponse, mais c'est probablement ce que je ferais probablement.

Modifier: Voici un lien Spring AOP pour vous aider à démarrer, si vous êtes passionné. C'est l'implémentation la plus accessible d'AOP que Iive rencontre pour Java.

En outre, étant donné les suggestions très simples de tout le monde, je devrais ajouter que l'AOP est pour quand vous ne voulez pas des choses comme le temps d'envahir votre code. Mais dans de nombreux cas, ce genre d'approche simple et facile est bien.


35
2017-10-07 20:13



System.currentTimeMillis();N'EST PAS une bonne approche pour mesurer la performance de vos algorithmes. Il mesure le temps total que vous passez en tant qu'utilisateur à regarder l'écran de l'ordinateur. Il inclut également le temps consommé par tout le reste fonctionnant sur votre ordinateur en arrière-plan. Cela pourrait faire une énorme différence dans le cas où vous avez beaucoup de programmes en cours d'exécution sur votre poste de travail.

Approche appropriée utilise java.lang.management paquet.

De http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking site Internet:

  • "Temps utilisateur" est le temps passé à exécuter le propre code de votre application.
  • "Heure système" correspond au temps passé à exécuter le code du système d'exploitation pour le compte de votre application (par exemple pour les E / S).

getCpuTime() méthode vous donne la somme de ceux:

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

public class CPUUtils {

    /** Get CPU time in nanoseconds. */
    public static long getCpuTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadCpuTime( ) : 0L;
    }

    /** Get user time in nanoseconds. */
    public static long getUserTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadUserTime( ) : 0L;
    }

    /** Get system time in nanoseconds. */
    public static long getSystemTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            (bean.getCurrentThreadCpuTime( ) - bean.getCurrentThreadUserTime( )) : 0L;
    }

}

33
2018-04-06 13:46



Avec Java 8, vous pouvez aussi faire quelque chose comme ça avec chaque normale méthodes:

Object returnValue = TimeIt.printTime(() -> methodeWithReturnValue());
//do stuff with your returnValue

avec TimeIt aime:

public class TimeIt {

public static <T> T printTime(Callable<T> task) {
    T call = null;
    try {
        long startTime = System.currentTimeMillis();
        call = task.call();
        System.out.print((System.currentTimeMillis() - startTime) / 1000d + "s");
    } catch (Exception e) {
        //...
    }
    return call;
}
}

Avec cette méthode, vous pouvez facilement mesurer le temps n'importe où dans votre code sans le casser. Dans cet exemple simple, je viens d'imprimer l'heure. Pouvez-vous ajouter un Switch pour TimeIt, par ex. pour imprimer uniquement l'heure dans DebugMode ou quelque chose.

Si vous travaillez avec Fonction vous pouvez faire quelque chose comme ça:

Function<Integer, Integer> yourFunction= (n) -> {
        return IntStream.range(0, n).reduce(0, (a, b) -> a + b);
    };

Integer returnValue = TimeIt.printTime2(yourFunction).apply(10000);
//do stuff with your returnValue

public static <T, R> Function<T, R> printTime2(Function<T, R> task) {
    return (t) -> {
        long startTime = System.currentTimeMillis();
        R apply = task.apply(t);
        System.out.print((System.currentTimeMillis() - startTime) / 1000d
                + "s");
        return apply;
    };
}

20
2017-11-25 22:47



Nous pouvons également utiliser la classe StopWatch des communs Apache pour mesurer le temps.

Exemple de code

org.apache.commons.lang.time.StopWatch sw = new org.apache.commons.lang.time.StopWatch();

System.out.println("getEventFilterTreeData :: Start Time : " + sw.getTime());
sw.start();

// Method execution code

sw.stop();
System.out.println("getEventFilterTreeData :: End Time : " + sw.getTime());

16
2017-12-03 04:37