web-dev-qa-db-fra.com

Mesurer le temps d'exécution pour une méthode Java

Comment calculer le temps pris pour l'exécution d'une méthode en Java?

247
Renuka

Vous pouvez prendre des instantanés d'horodatage avant et après, puis répétez les expériences plusieurs fois pour obtenir une moyenne des résultats . Il existe également des profileurs qui peuvent le faire pour vous.


Extrait du livre "Performance de la plate-forme Java: stratégies et tactiques":

avec System.currentTimeMillis ()

class TimeTest1 {
   public static void main(String[] args) {

      long startTime = System.currentTimeMillis();

      long total = 0;
      for (int i = 0; i < 10000000; i++) {
         total += i;
      }

      long stopTime = System.currentTimeMillis();
      long elapsedTime = stopTime - startTime;
      System.out.println(elapsedTime);
   }
}

avec une classe StopWatch

Vous pouvez utiliser cette classe StopWatch et appeler start() et stop avant et après la méthode.

class TimeTest2 {
   public static void main(String[] args) {

      Stopwatch timer = new Stopwatch().start();

      long total = 0;
      for (int i = 0; i < 10000000; i++) {
         total += i;
      }

      timer.stop();
      System.out.println(timer.getElapsedTime());
   }
}

Voir ici .


NetBeans Profiler:

Application Performance Application

Profils de performance performances de l’UC au niveau de la méthode (temps d’exécution) . Vous pouvez choisir de profiler l’ensemble de l’application ou une partie de celle-ci.

Voir ici .

223
bakkal

Pour être plus précis, j'utiliserais la méthode nanoTime() plutôt que currentTimeMillis():

long startTime = System.nanoTime();
myCall(); 
long stopTime = System.nanoTime();
System.out.println(stopTime - startTime);

Dans Java 8 (le format de sortie est ISO-8601):

Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end)); // prints PT1M3.553S

Goyave chronomètre :

Stopwatch stopwatch = Stopwatch.createStarted();
myCall();
stopwatch.stop(); // optional
System.out.println("Time elapsed for myCall() is "+ stopwatch.elapsed(MILLISECONDS));
212
Vitalii Fedorenko

Vérifiez ceci: System.currentTimeMillis .

Avec cela, vous pouvez calculer le temps de votre méthode en faisant:

long start = System.currentTimeMillis();
class.method();
long time = System.currentTimeMillis() - start;
38
functional

Si vous développez des applications pour Android , vous devriez essayer la classe TimingLogger .
Consultez ces articles décrivant l’utilisation de la classe d’assistance TimingLogger:

31
JJD

Vous voudrez peut-être penser à la programmation orientée aspect. Vous ne voulez pas jeter votre code avec des timings. Vous voulez pouvoir les désactiver et les déclarer de manière déclarative.

Si vous utilisez Spring, regardez leur classe MethodInterceptor .

12
duffymo

Si vous écrivez actuellement l'application, la réponse consiste à utiliser System.currentTimeMillis ou System.nanoTime à la fin indiquée par les personnes précédentes.

Mais si vous avez déjà écrit le code et que vous ne voulez pas le changer, il vaut mieux utiliser les intercepteurs de méthode de Spring. Ainsi, par exemple, votre service est:

public class MyService { 
    public void doSomething() {
        for (int i = 1; i < 10000; i++) {
            System.out.println("i=" + i);
        }
    }
}

Pour éviter de changer le service, vous pouvez écrire votre propre intercepteur de méthode:

public class ServiceMethodInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = methodInvocation.proceed();
        long duration = System.currentTimeMillis() - startTime;
        Method method = methodInvocation.getMethod();
        String methodName = method.getDeclaringClass().getName() + "." + method.getName();
        System.out.println("Method '" + methodName + "' took " + duration + " milliseconds to run");
        return null;
    }
}

Il existe également des API open source disponibles pour Java, par exemple. BTrace . ou profileur Netbeans comme suggéré ci-dessus par @bakkal et @Saikikos. Merci.

9
kinshuk4

Comme proposé, nanoTime () est très précis sur des échelles de temps courtes. Lorsque cette précision est requise, vous devez faire attention à ce que vous mesurez vraiment. Surtout ne pas mesurer le nanotime lui-même

long start1 = System.nanoTime();
// maybe add here a call to a return to remove call up time, too.
// Avoid optimization 
long start2 = System.nanoTime();
myCall(); 
long stop = System.nanoTime();
long diff = stop - 2*start2 + start1;

System.out.println(diff + " ns");

En passant, vous mesurerez différentes valeurs pour le même appel en raison de

  • autre charge sur votre ordinateur (arrière-plan, réseau, mouvement de la souris, interruptions, commutation de tâches, threads)
  • remplissages de cache (froid, chaud)
  • compilation jit (pas d'optimisation, baisse des performances due à l'exécution du compilateur, amélioration des performances due au compilateur (mais parfois, le code avec jit est plus lent que sans!))
5
stefan bachert

Nanotime n'est même pas bon pour le temps écoulé, car il dérive beaucoup plus que currentTimeMillis. De plus, nanotime a tendance à fournir une précision excessive au détriment de la précision. Il est donc extrêmement incohérent et doit être amélioré.

CurrentTimeMillis (bien que presque aussi mauvais) fait mieux en termes d'équilibrage exact et exact.

1
sarvesh