Gibt es eine Stoppuhr in Java?

107

Gibt es eine Stoppuhr in Java? Bei Google finde ich nur Code von Stoppuhren, die nicht funktionieren - sie geben immer 0 Millisekunden zurück.

Dieser Code, den ich gefunden habe, funktioniert nicht, aber ich verstehe nicht warum.

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
quelle
10
Und wie stellen Sie fest, dass es nicht funktioniert hat? (Vielleicht messen Sie etwas, dessen Ausführung weniger Zeit in
Nr.
5
Bitte posten Sie den Code, wie Sie diese Klasse testen ...
DXTR66
2
Ich wollte nur erwähnen, dass dies eine der Lehrbuchfragen in "Einführung in die Java-Programmierung, umfassende Version (9. Ausgabe)" ist.
Sam
2
Bitte nicht currentTimeMillis()für die Produktion verwenden, da es an das Datum / die Uhrzeit des Systems gebunden ist und nicht garantiert eintönig ist (z. B. kann es zu einer negativen verstrichenen Zeit kommen). Zur Messung der Zeitnutzung nanoTime()- es ist garantiert eintönig und genau für Messzwecke vorgesehen. Siehe docs.oracle.com/javase/8/docs/api/java/lang/…
Nikita Bosik

Antworten:

90

Verwenden Sie die StopwatchKlasse von Guava .

Ein Objekt, das die verstrichene Zeit in Nanosekunden misst. Es ist System.nanoTime()aus mehreren Gründen nützlich, die verstrichene Zeit mit dieser Klasse zu messen, anstatt direkt aufzurufen :

  • Eine alternative Zeitquelle kann aus Test- oder Leistungsgründen ersetzt werden.
  • Wie von nanoTime dokumentiert, hat der zurückgegebene Wert keine absolute Bedeutung und kann nur als relativ zu einem anderen Zeitstempel interpretiert werden, der von nanoTime zu einem anderen Zeitpunkt zurückgegeben wird. Stoppuhr ist eine effektivere Abstraktion, da nur diese relativen Werte verfügbar gemacht werden, nicht die absoluten.
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"
Hilfsmethode
quelle
2
Guaven Stoppuhr fehlt getStartTime(), Apache fehlt isRunning()ahhhh
To Kra
3
@ToKra Was würdest du überhaupt mit der Startzeit machen? Da es Nano-Zeit ist, können Sie es sowieso nicht für irgendetwas Sinnvolles verwenden, wie in den Dokumenten beschrieben.
Trejkaz
1
Jetzt verwenden Sie dies, um die Millisekunden abzurufen: long stopWatch = stopWatch.elapsed (TimeUnit.MILLISECONDS);
PHPGuru
Um welche Guavenversion handelt es sich? Ich habe 1.8 verwendet und die Stoppuhr-Klasse
Laser Infinite
58

Jetzt können Sie etwas ausprobieren wie:

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

Die Ausgabe erfolgt in ISO 8601.

Valtoni Boaventura
quelle
1
Schnell und einfach, vielen Dank! Hilft, die Dauer der Aufgabe von Anfang an zu verfolgen.
ndm13
Was ist, wenn Sie die Systemzeit im Ruhezustand ändern?
Peteter
1
@Peteter ist nur ein Beispiel. Wenn Sie sich auf einer Linux-Box befinden, müssen Sie sich mit Hardware Clock und Kernel Managed Clock befassen. Wenn Sie die Hardware-Uhr ändern, ist keine davon betroffen, aber in der vom Kernel verwalteten Uhr treten Probleme auf: Instant.now () ruft die Systemzeit ab und zeigt ein falsches Zeitintervall an.
Valtoni Boaventura
Ich wusste nicht einmal, dass es auf Android funktioniert. Gut zu wissen :)
Valtoni Boaventura
Nicht zu vergessen java.time.Instant ist unveränderlich und threadsicher :)
Amos Kosgei
38

Die Feder bietet eine elegante org.springframework.util.StopWatchKlasse (Federkernmodul).

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

Verwenden Sie System.currentTimeMillis()diese Option , um die Start- und Endzeit abzurufen und die Differenz zu berechnen.

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

Weitere Infos in diesem Tutorial

user2374612
quelle
Wie an anderer Stelle erwähnt, ist currentTimeMillis () an das Datum / die Uhrzeit des Systems gebunden und es wird nicht garantiert, dass es eintönig ist (z. B. kann es zu einer negativen verstrichenen Zeit kommen).
Oligofren
8

Der Code funktioniert nicht, da die verstrichene Variable in getElapsedTimeSecs()kein floatoder ist double.

asfer
quelle
7

Es gibt kein eingebautes Stoppuhr-Dienstprogramm, aber ab JSR-310 (Java 8 Time) können Sie dies einfach tun.

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

Ich habe dies nicht richtig bewertet, aber ich würde vermuten, dass die Verwendung der Stoppuhr von Guava effektiver ist.

Matsa
quelle
3

Einfache sofort einsatzbereite Stoppuhrklasse:

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

Verwendung:

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

Verwenden Sie: com.google.common.base.Stopwatch, es ist einfach und leicht.

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

Beispiel:

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

"Do something"

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

Diese Aufgabe dauerte 112 Mühlen

Luke_P
quelle
2

Versuche dies

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
quelle
1
Wie an anderer Stelle erwähnt, ist currentTimeMillis () an das Datum / die Uhrzeit des Systems gebunden und es wird nicht garantiert, dass es eintönig ist (z. B. kann es zu einer negativen verstrichenen Zeit kommen).
Oligofren
2

Versuche dies:

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

}

Verwenden:

StopWatch sw = new StopWatch();
...
sw.startTiming();
...
String interval = sw.stopTiming();
Oke Uwechue
quelle
2
DateUtils ist Teil von Apache Commons. Warum nicht einfach ihre StopWatch verwenden?
Bill Effin Murray
In den meisten Fällen verwenden Sie eine allgemeine Bibliothek, wie in anderen Antworten erwähnt (z. B. Apache Commons). Sie können sogar nur Teile der Bibliothek mitnehmen, wenn Sie nicht alles benötigen.
Guyarad
2

Versuche dies.

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

Verwendung:

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

Konsole:

StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.
KS
quelle
Obwohl dies möglicherweise das ist, wonach in der Frage gefragt wurde oder nicht, hat mir Ihre Antwort bei meinem Problem geholfen. Danke dir.
Toiletduck
currentTimeMillis()ist an das Datum / die Uhrzeit des Systems gebunden und garantiert nicht eintönig (z. B. können Sie eine negative verstrichene Zeit erhalten).
Oligofren
Wenn Sie sich entscheiden, Ihre eigenen zu erstellen, verwenden Sie einfach, System.nanoTime()um immer korrekte Ergebnisse zu erhalten.
Oligofren
2

Performetrics bietet eine praktische Stoppuhrklasse, genau so, wie Sie es brauchen. Es kann die Wanduhrzeit und mehr messen: Bei Bedarf misst es auch die CPU-Zeit (Benutzerzeit und Systemzeit). Es ist klein, kostenlos und kann von Maven Central heruntergeladen werden. Weitere Informationen und Beispiele finden Sie hier: 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  |
// +-----------------+----------------------+--------------+

Sie können die Metriken in jede Zeiteinheit konvertieren (Nanosekunden, Millisekunden, Sekunden usw.)

PS: Ich bin der Autor des Tools.

Oswaldo Junior
quelle
1

Versuche dies.

Java Stopwatch voll funktionsfähige Lösung

Hier erhalten Sie eine voll funktionsfähige Lösung.

Nur ein Ausschnitt aus der oben verlinkten Lösung:

Sie können eine Klasse wie den folgenden Code erstellen und die Start- und Stoppmethode dieser Klasse vor und nach dem Codeabschnitt verwenden, um die benötigte Zeit zu messen.

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.";
  }

}}

Danke dir.

Sukriti Sarkar
quelle
1
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert.
AS Mackay
Vielen Dank an @ASMackay für Ihren Vorschlag. Ich stimme völlig mit Ihnen.
Sukriti Sarkar