Y a-t-il un chronomètre à Java?

107

Y a-t-il un chronomètre à Java? Sur google, je ne trouve que le code des chronomètres qui ne fonctionnent pas - ils renvoient toujours 0 millisecondes.

Ce code que j'ai trouvé ne fonctionne pas mais je ne vois pas pourquoi.

public class StopWatch {

  private long startTime = 0;
  private long stopTime = 0;
  private boolean running = false;


  public void start() {
    this.startTime = System.currentTimeMillis();
    this.running = true;
  }


  public void stop() {
    this.stopTime = System.currentTimeMillis();
    this.running = false;
  }


  //elaspsed time in milliseconds
  public long getElapsedTime() {
    long elapsed;
    if (running) {
      elapsed = (System.currentTimeMillis() - startTime);
    } else {
      elapsed = (stopTime - startTime);
    }
    return elapsed;
  }


  //elaspsed time in seconds
  public long getElapsedTimeSecs() {
    long elapsed;
    if (running) {
      elapsed = ((System.currentTimeMillis() - startTime) / 1000);
    } else {
      elapsed = ((stopTime - startTime) / 1000);
    }
    return elapsed;
  }
}
user1007522
la source
10
Et comment déterminez-vous que cela n'a pas fonctionné? (peut-être que vous mesurez quelque chose qui prend moins de temps à exécuter que la précision de System.currentTimeMillis ())
nos
5
S'il vous plaît poster le code comment vous testez cette classe ...
DXTR66
2
Je voulais juste noter que c'est l'une des questions du manuel dans "Introduction à la programmation Java, version complète (9e édition)".
Sam
2
Veuillez ne pas l'utiliser currentTimeMillis()pour la production, car elle est liée à la date / heure du système et n'est pas garantie d'être monotone (par exemple, vous pouvez obtenir un temps écoulé négatif). Pour mesurer l'utilisation du temps nanoTime()- il est garanti monotone et destiné exactement à des fins de mesure. Voir docs.oracle.com/javase/8/docs/api/java/lang/…
Nikita Bosik

Réponses:

90

Utilisez la Stopwatchclasse de Guava .

Un objet qui mesure le temps écoulé en nanosecondes. Il est utile de mesurer le temps écoulé en utilisant cette classe au lieu d'appels directs à System.nanoTime()pour plusieurs raisons:

  • Une autre source de temps peut être remplacée, pour des raisons de test ou de performances.
  • Comme documenté par nanoTime, la valeur renvoyée n'a pas de signification absolue et ne peut être interprétée que comme relative à un autre horodatage renvoyé par nanoTime à un moment différent. Le chronomètre est une abstraction plus efficace car il n'expose que ces valeurs relatives, pas les valeurs absolues.
Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional

long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);

log.info("that took: " + stopwatch); // formatted string like "12.3 ms"
méthode d'aide
la source
2
le chronomètre des goyaves est manquant getStartTime(), il manque apache isRunning()ahhhh
To Kra
3
@ToKra Que feriez-vous de toute façon avec l'heure de début? Comme il est temps nano, vous ne pouvez pas l'utiliser pour quoi que ce soit de significatif, comme décrit dans la documentation.
Trejkaz
1
Vous utilisez maintenant ceci pour obtenir les millisecondes: long stopWatch = stopWatch.elapsed (TimeUnit.MILLISECONDS);
PHPGuru
De quelle version de goyave s'agit-il? J'ai utilisé 1.8 et je n'ai pas trouvé la classe Chronomètre
Laser Infinite
58

Maintenant, vous pouvez essayer quelque chose comme:

Instant starts = Instant.now();
Thread.sleep(10);
Instant ends = Instant.now();
System.out.println(Duration.between(starts, ends));

La sortie est en ISO 8601.

Valtoni Boaventura
la source
1
Rapide et facile, merci beaucoup! Aide à suivre la durée de la tâche depuis le début.
ndm13
Que faire si vous modifiez l'heure du système pendant le sommeil?
Peteter
1
@ Peteter n'est qu'un exemple. Si vous êtes sous Linux, vous devez gérer l'horloge matérielle et l'horloge gérée par le noyau. Si vous changez l'horloge matérielle, aucune ne sera affectée, mais dans l'horloge gérée par le noyau, vous aurez des problèmes: Instant.now () obtient l'heure du système et affichera un intervalle de temps erroné.
Valtoni Boaventura
Je ne savais même pas que cela fonctionnait sur Android. Bon à savoir :)
Valtoni Boaventura
Sans oublier java.time.Instant est immuable et thread-safe :)
Amos Kosgei
38

Spring fournit une org.springframework.util.StopWatchclasse élégante (module à noyau de ressort).

StopWatch stopWatch = new StopWatch();
stopWatch.start();
     // Do something
stopWatch.stop();
     System.out.println(stopWatch.getTotalTimeMillis());
Larsen
la source
8

Utilisez System.currentTimeMillis()pour obtenir l'heure de début et l'heure de fin et calculer la différence.

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

Plus d'informations dans ce tutoriel

utilisateur2374612
la source
Comme dit ailleurs, currentTimeMillis () est lié à la date / heure du système et n'est pas garanti d'être monotone (par exemple, vous pouvez obtenir un temps écoulé négatif).
oligofren
8

Le code ne fonctionne pas car la variable écoulée dans getElapsedTimeSecs()n'est pas un floatou double.

asfer
la source
7

Il n'y a pas d'utilitaire Stopwatch intégré, mais à partir de JSR-310 (Java 8 Time), vous pouvez le faire simplement.

ZonedDateTime now = ZonedDateTime.now();
// Do stuff
long seconds = now.until(ZonedDateTime.now(), ChronoUnit.SECONDS);

Je n'ai pas évalué cela correctement, mais je suppose que l'utilisation du chronomètre de Guava est plus efficace.

matsa
la source
3

Classe Chronomètre simple prête à l'emploi:

import java.time.Duration;
import java.time.Instant;

public class StopWatch {

    Instant startTime, endTime;
    Duration duration;
    boolean isRunning = false;

    public void start() {
        if (isRunning) {
            throw new RuntimeException("Stopwatch is already running.");
        }
        this.isRunning = true;
        startTime = Instant.now();
    }

    public Duration stop() {
        this.endTime = Instant.now();
        if (!isRunning) {
            throw new RuntimeException("Stopwatch has not been started yet");
        }
        isRunning = false;
        Duration result = Duration.between(startTime, endTime);
        if (this.duration == null) {
            this.duration = result;
        } else {
            this.duration = duration.plus(result);
        }

        return this.getElapsedTime();
    }

    public Duration getElapsedTime() {
        return this.duration;
    }

    public void reset() {
        if (this.isRunning) {
            this.stop();
        }
        this.duration = null;
    }
}

Usage:

StopWatch sw = new StopWatch();
sw.start();
    // doWork()
sw.stop();
System.out.println( sw.getElapsedTime().toMillis() + "ms");
Jonas_Hess
la source
3

utilisez: com.google.common.base.Stopwatch, c'est simple et facile.

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>

exemple:

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

"Do something"

logger.debug("this task took " + stopwatch.stop().elapsedTime(TimeUnit.MILLISECONDS) + " mills");

cette tâche a nécessité 112 moulins

Luke_P
la source
2

essaye ça

import java.awt.event.*;

import java.awt.*;

import javax.swing.*;

public class millis extends JFrame implements ActionListener, Runnable
    {

     private long startTime;
     private final static java.text.SimpleDateFormat timerFormat = new java.text.SimpleDateFormat("mm : ss.SSS");
     private final JButton startStopButton= new JButton("Start/stop");
     private Thread updater;
     private boolean isRunning= false;
     private final Runnable displayUpdater= new Runnable()
         {
         public void run()
             {
             displayElapsedTime(System.currentTimeMillis() - millis.this.startTime);
         }
     };
     public void actionPerformed(ActionEvent ae)
         {
         if(isRunning)
             {
             long elapsed= System.currentTimeMillis() - startTime;
             isRunning= false;
             try
                 {
                 updater.join();
                 // Wait for updater to finish
             }
             catch(InterruptedException ie) {}
             displayElapsedTime(elapsed);
             // Display the end-result
         }
         else
             {
             startTime= System.currentTimeMillis();
             isRunning= true;
             updater= new Thread(this);
             updater.start();
         }
     }
     private void displayElapsedTime(long elapsedTime)
         {
         startStopButton.setText(timerFormat.format(new java.util.Date(elapsedTime)));
     }
     public void run()
         {
         try
             {
             while(isRunning)
                 {
                 SwingUtilities.invokeAndWait(displayUpdater);
                 Thread.sleep(50);
             }
         }
         catch(java.lang.reflect.InvocationTargetException ite)
             {
             ite.printStackTrace(System.err);
             // Should never happen!
         }
         catch(InterruptedException ie) {}
         // Ignore and return!
     }
     public millis()
         {
         startStopButton.addActionListener(this);
         getContentPane().add(startStopButton);
         setSize(100,50);
         setVisible(true);
     }
     public static void main(String[] arg)
         {
         new Stopwatch().addWindowListener(new WindowAdapter()
             {
             public void windowClosing(WindowEvent e)
                 {
                 System.exit(0);
             }
         });
         millis s=new millis();
         s.run();
     }
}
andrewsi
la source
1
Comme dit ailleurs, currentTimeMillis () est lié à la date / heure du système et n'est pas garanti d'être monotone (par exemple, vous pouvez obtenir un temps écoulé négatif).
oligofren
2

Essaye ça:

/*
 * calculates elapsed time in the form hrs:mins:secs
 */
public class StopWatch
{ 
    private Date startTime;

    public void startTiming()
    {
        startTime = new Date();
    }

    public String stopTiming()
    {
        Date stopTime = new Date();
        long timediff = (stopTime.getTime() - startTime.getTime())/1000L;
        return(DateUtils.formatElapsedTime(timediff));
    }

}

Utilisation:

StopWatch sw = new StopWatch();
...
sw.startTiming();
...
String interval = sw.stopTiming();
Oke Uwechue
la source
2
DateUtils fait partie d'Apache Commons, pourquoi ne pas simplement utiliser leur StopWatch?
Bill Effin Murray
Dans la plupart des cas, vous utiliserez une bibliothèque commune comme mentionné dans d'autres réponses (Apache Commons par exemple). Vous pouvez même ne prendre que des parties de la bibliothèque avec si vous n'avez pas besoin de tout.
guyarad
2

Essaye ça.

public class StopWatch { 

      private long startTime = 0;
      private long stopTime = 0;

      public StopWatch()
      {
            startTime = System.currentTimeMillis();
      }

      public void start() {
        startTime = System.currentTimeMillis();
      }

      public void stop() {
        stopTime = System.currentTimeMillis();
        System.out.println("StopWatch: " + getElapsedTime() + " milliseconds.");
        System.out.println("StopWatch: " + getElapsedTimeSecs() + " seconds.");
      }

      /**
       * @param process_name
       */
      public void stop(String process_name) {
            stopTime = System.currentTimeMillis();
            System.out.println(process_name + " StopWatch: " + getElapsedTime() + " milliseconds.");
            System.out.println(process_name + " StopWatch: " + getElapsedTimeSecs() + " seconds.");
      }      

      //elaspsed time in milliseconds
      public long getElapsedTime() {
          return stopTime - startTime;
      }

      //elaspsed time in seconds
      public double getElapsedTimeSecs() {
        double elapsed;
          elapsed = ((double)(stopTime - startTime)) / 1000;
        return elapsed;
      }
} 

Usage:

StopWatch watch = new StopWatch();
// do something
watch.stop();

Console:

StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.
KS
la source
Bien que cela puisse être ou non ce qui était demandé dans la question, votre réponse m'a aidé avec mon problème. Je vous remercie.
Toiletduck
currentTimeMillis()est liée à la date / heure du système et n'est pas garantie d'être monotone (par exemple, vous pouvez obtenir un temps écoulé négatif).
oligofren
Si vous décidez de créer le vôtre, utilisez simplement System.nanoTime()pour toujours obtenir des résultats corrects.
oligofren
2

Performetrics fournit une classe Chronomètre pratique, exactement comme vous en avez besoin. Il peut mesurer l'heure de l'horloge murale et plus encore: il mesure également le temps CPU (temps utilisateur et temps système) si vous en avez besoin. C'est petit, gratuit et vous pouvez le télécharger depuis Maven Central. Plus d'informations et d'exemples peuvent être trouvés ici: https://obvj.net/performetrics

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

// Your code

sw.stop();
sw.printStatistics(System.out);

// Sample output:
// +-----------------+----------------------+--------------+
// | Counter         |         Elapsed time | Time unit    |
// +-----------------+----------------------+--------------+
// | Wall clock time |             85605718 | nanoseconds  |
// | CPU time        |             78000500 | nanoseconds  |
// | User time       |             62400400 | nanoseconds  |
// | System time     |             15600100 | nanoseconds  |
// +-----------------+----------------------+--------------+

Vous pouvez convertir les métriques en n'importe quelle unité de temps (nanosecondes, millisecondes, secondes, etc.)

PS: Je suis l'auteur de l'outil.

Oswaldo Junior
la source
1

Essaye ça.

Solution complète de chronomètre Java

Ici, vous obtiendrez une solution entièrement fonctionnelle.

Juste un extrait de la solution liée ci-dessus:

Vous pouvez créer une classe comme le code ci-dessous et utiliser la méthode de démarrage et d'arrêt de cette classe avant et après la section de code, vous souhaitez mesurer le temps nécessaire.

public class Stopwatch{
  private long startTime;
  private long stopTime;

  /**
   starting the stop watch.
  */
  public void start(){
        startTime = System.nanoTime();
  }

  /**
   stopping the stop watch.
  */
  public void stop()
  {     stopTime = System.nanoTime(); }

  /**
  elapsed time in nanoseconds.
  */
  public long time(){
        return (stopTime - startTime);
  }

  public String toString(){
      return "elapsed time: " + time() + " nanoseconds.";
  }

}

Je vous remercie.

Sukriti Sarkar
la source
1
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses aux liens uniquement peuvent devenir invalides si la page liée change.
AS Mackay
Merci @ASMackay pour votre suggestion. Je suis complètement d'accord avec toi.
Sukriti Sarkar