C'è un cronometro in Java?


107

C'è un cronometro in Java? Su google trovo solo il codice dei cronometri che non funzionano - restituiscono sempre 0 millisecondi.

Questo codice che ho trovato non funziona ma non vedo il motivo.

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

10
E come determini che non ha funzionato? (forse stai misurando qualcosa che richiede meno tempo per essere eseguito rispetto alla precisione di System.currentTimeMillis ())
nn


2
Volevo solo notare che questa è una delle domande dei libri di testo in "Introduzione alla programmazione Java, versione completa (9a edizione)".
Sam

2
Si prega di non utilizzare currentTimeMillis()per la produzione, poiché è legato alla data / ora del sistema e non è garantito che sia monotono (ad esempio, è possibile ottenere un tempo trascorso negativo). Per la misurazione del tempo nanoTime(): è garantito che sia monotono e inteso esattamente per scopi di misurazione. Vedi docs.oracle.com/javase/8/docs/api/java/lang/…
Nikita Bosik

Risposte:



90

Usa la Stopwatchclasse di Guava .

Un oggetto che misura il tempo trascorso in nanosecondi. È utile misurare il tempo trascorso utilizzando questa classe invece delle chiamate dirette a System.nanoTime()per alcuni motivi:

  • È possibile sostituire un'origine dell'ora alternativa, per motivi di test o prestazioni.
  • Come documentato da nanoTime, il valore restituito non ha alcun significato assoluto e può essere interpretato solo come relativo a un altro timestamp restituito da nanoTime in un momento diverso. Il cronometro è un'astrazione più efficace perché espone solo questi valori relativi, non quelli assoluti.
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"

2
Manca il cronometro di guaiave getStartTime(), manca l' apache isRunning()ahhhh
To Kra

3
@ToKra Cosa faresti comunque con l'ora di inizio? Dato che è tempo nano, non puoi usarlo comunque per qualcosa di significativo, come descritto nei documenti.
Trejkaz

1
Ora lo usi per ottenere i millisecondi: long stopWatch = stopWatch.elapsed (TimeUnit.MILLISECONDS);
PHPGuru

Quale versione guava è? Ho usato 1.8 e non ha trovato la classe Stopwatch
Laser Infinite

58

Ora puoi provare qualcosa come:

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

L'output è in ISO 8601.


1
Facile e veloce, grazie mille! Aiuta a tenere traccia della durata dell'attività dall'inizio.
ndm13

Cosa succede se si modifica l'ora del sistema durante il sonno?
Peteter

1
@ Peter è solo un esempio. Se sei su una macchina Linux, devi gestire l'orologio hardware e l'orologio gestito dal kernel. Se si modifica l'orologio hardware, nessuno sarà influenzato ma nell'orologio gestito dal kernel si avranno problemi: Instant.now () ottiene l'ora di sistema e mostrerà un intervallo di tempo sbagliato.
Valtoni Boaventura

Non sapevo nemmeno che funzionasse su Android. Buono a sapersi :)
Valtoni Boaventura

Senza dimenticare java.time.Instant è immutabile e thread-safe :)
Amos Kosgei

38

Spring fornisce una org.springframework.util.StopWatchclasse elegante (modulo spring-core).

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

8

Utilizzare System.currentTimeMillis()per ottenere l'ora di inizio e l'ora di fine e calcolare la differenza.

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

Maggiori informazioni in questo tutorial


Come detto altrove, currentTimeMillis () è legato alla data / ora del sistema e non è garantito che sia monotono (ad esempio, è possibile ottenere un tempo trascorso negativo).
oligofren

8

Il codice non funziona perché la variabile trascorsa in getElapsedTimeSecs()non è un floato double.


7

Non esiste un'utilità Stopwatch incorporata ma a partire da JSR-310 (Java 8 Time) puoi farlo semplicemente.

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

Non l'ho valutato correttamente, ma immagino che usare il cronometro di Guava sia più efficace.



3

Semplice classe cronometro fuori dagli schemi:

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

Uso:

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

3

utilizzare: com.google.common.base.Stopwatch, è semplice e facile.

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

esempio:

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

"Do something"

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

questo compito ha richiesto 112 mulini


2

prova questo

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

1
Come detto altrove, currentTimeMillis () è legato alla data / ora del sistema e non è garantito che sia monotono (ad esempio, è possibile ottenere un tempo trascorso negativo).
oligofren

2

Prova questo:

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

}

Uso:

StopWatch sw = new StopWatch();
...
sw.startTiming();
...
String interval = sw.stopTiming();

2
DateUtils fa parte di Apache Commons, perché non usare semplicemente il loro StopWatch?
Bill Effin Murray

Nella maggior parte dei casi utilizzerai alcune librerie comuni come menzionato in altre risposte (Apache Commons per esempio). Puoi anche portare solo parti della libreria se non hai bisogno di tutto.
guyarad

2

Prova questo.

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

Uso:

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

Console:

StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.

Sebbene questo possa o meno essere ciò che è stato chiesto nella domanda, la tua risposta mi ha aiutato con il mio problema. Grazie.
Toiletduck

currentTimeMillis()è legato alla data / ora del sistema e non è garantito che sia monotono (ad esempio, è possibile ottenere un tempo trascorso negativo).
oligofren

Se decidi di crearne uno tuo, usalo System.nanoTime()per ottenere sempre risultati corretti.
oligofren

2

Performetrics offre una comoda lezione di cronometro, proprio come ti serve. Può misurare il tempo dell'orologio da parete e altro ancora: misura anche il tempo della CPU (tempo dell'utente e tempo di sistema) se necessario. È piccolo, gratuito e può essere scaricato da Maven Central. Ulteriori informazioni ed esempi sono disponibili qui: 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  |
// +-----------------+----------------------+--------------+

Puoi convertire le metriche in qualsiasi unità di tempo (nanosecondi, millisecondi, secondi, ecc ...)

PS: sono l'autore dello strumento.



1

Prova questo.

Soluzione cronometro Java completamente funzionante

Qui otterrai una soluzione completamente funzionante.

Solo uno snippet della soluzione sopra collegata:

È possibile creare una classe come il codice riportato di seguito e utilizzare il metodo di avvio e arresto di questa classe prima e dopo la sezione del codice, si desidera misurare il tempo impiegato.

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

}

Grazie.


1
Sebbene questo collegamento possa rispondere alla domanda, è meglio includere le parti essenziali della risposta qui e fornire il collegamento come riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia.
AS Mackay

Grazie @ASMackay per il tuo suggerimento. Sono completamente d'accordo con voi.
Sukriti Sarkar
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.