Чи є секундомір на Яві?


107

Чи є секундомір на Яві? У Google я знаходжу лише код секундомірів, які не працюють - вони завжди повертають 0 мілісекунд.

Цей код, який я знайшов, не працює, але не розумію, чому.

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
І як ви визначите, що це не спрацювало? (Можливо , ви вимірюєте то , що займає менше часу , щоб виконати , ніж точність System.currentTimeMillis ())
NOS

5
Будь ласка, опублікуйте код, як ви протестуєте цей клас ...
DXTR66

2
Просто хотів зазначити, що це одне з питань підручника у "Введення в програмування Java, всебічна версія (9-е видання)".
Сем

2
Будь ласка, не використовуйте currentTimeMillis()для виробництва, оскільки він прив’язаний до дати / часу системи і не гарантується одноманітністю (наприклад, ви можете отримати негативний минулий час). Для вимірювання часу nanoTime()- це гарантовано одноманітно і призначене саме для вимірювання. Дивіться docs.oracle.com/javase/8/docs/api/java/lang/…
Микита Босик

Відповіді:



90

Використовуйте клас ГуавиStopwatch .

Об'єкт, який вимірює минулий час у наносекундах. Корисно вимірювати минулий час, використовуючи цей клас, а не прямі дзвінки з System.nanoTime()кількох причин:

  • Альтернативне джерело часу може бути замінене з метою тестування або ефективності.
  • Як задокументовано nanoTime, повернене значення не має абсолютного значення, і його можна інтерпретувати лише як відносно іншої часової позначки, поверненої nanoTime в інший час. Секундомір - це більш ефективна абстракція, оскільки вона викриває лише ці відносні значення, а не абсолютні.
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
Відсутній секундомір гуави getStartTime(), апаш відсутній isRunning()ааааа
До

3
@ToKra Що б ти зробив із часом початку? Оскільки це час нано, ви не можете використовувати його для будь-якого сенсу, як описано в документах.
Трежказ

1
Тепер ви використовуєте це для отримання мілісекунд: довга stopWatch = stopWatch.elapsed (TimeUnit.MILLISECONDS);
PHPGuru

Яка це версія гуави? Я використав 1,8, і він не знайшов секундомір класу
Laser Infinite

58

Тепер ви можете спробувати щось на кшталт:

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

Вихідні дані відповідають ISO 8601.


1
Швидко і просто, дуже дякую! Допомагає відстежувати тривалість завдання від початку.
ndm13

Що робити, якщо змінити системний час під час сну?
Пітер

1
@Peteter - це єдиний приклад. Якщо ви знаходитесь у вікні linux, ви повинні мати справу з апаратними та керованими ядрами. Якщо ви зміните апаратний годинник, це не вплине, але в керованому ядром годиннику ви будете мати проблеми: Instant.now () отримає системний час і покаже неправильний часовий інтервал.
Валтоні Боавентура

Я навіть не знав, що це працює на Android.
Приємно

Не забуваючи java.time.Instant є незмінним і безпечним для потоків :)
Amos

38

Spring забезпечує елегантний org.springframework.util.StopWatchклас (модуль пружини).

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

8

Використовуйте, 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);
  }
} 

Більше інформації в цьому підручнику


Як сказано в іншому місці, currentTimeMillis () прив’язаний до дати / часу системи і не гарантується одноманітністю (наприклад, ви можете отримати негативний минулий час).
олігофрен


7

Не існує вбудованої утиліти секундоміра, але в JSR-310 (Java 8 Time) ви можете це зробити просто.

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

Я не зробив це на належному рівні, але я б припустив, що використання секундоміра Гуави є більш ефективним.



3

Простий поза класом секундомір:

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

Використання:

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

3

використання: com.google.common.base.Stopwatch, його просто та легко.

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

приклад:

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

"Do something"

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

це завдання зайняло 112 млинів


2

спробуйте це

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
Як сказано в іншому місці, currentTimeMillis () прив’язаний до дати / часу системи і не гарантується одноманітністю (наприклад, ви можете отримати негативний минулий час).
олігофрен

2

Спробуйте це:

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

}

Використання:

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

2
DateUtils є частиною Apache Commons, чому б просто не використовувати їх StopWatch?
Білл Еффін Мюррей

У більшості випадків ви використовуєте якусь загальну бібліотеку, як згадується в інших відповідях (наприклад, Apache Commons). Ви навіть можете взяти лише частини бібліотеки, якщо вам все не потрібно.
guyarad

2

Спробуйте це.

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

Використання:

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

Консоль:

StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.

Хоча це може бути, а може і не бути тим, про що просили запитання, ваша відповідь допомогла мені з моєю проблемою. Дякую.
Toiletduck

currentTimeMillis()прив’язаний до дати / часу системи і не гарантується одноманітністю (наприклад, ви можете отримати негативний минулий час).
олігофрен

Якщо ви вирішили створити свій власний, просто використовуйте System.nanoTime()для отримання правильних результатів.
олігофрен

2

Performetrics забезпечує зручний клас секундоміра, точно так, як вам потрібно. Він може вимірювати час настінних годин і більше: він також вимірює час процесора (час користувача та системний час), якщо вам потрібно. Він невеликий, безкоштовний і його можна завантажити з Maven Central. Більше інформації та прикладів можна знайти тут: 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  |
// +-----------------+----------------------+--------------+

Ви можете конвертувати показники в будь-яку одиницю часу (наносекунд, мілісекунд, секунд тощо).

PS: Я автор інструменту.



1

Спробуйте це.

Java секундомір повністю працює рішення

Тут ви отримаєте повністю працююче рішення.

Просто фрагмент із вищезгаданого рішення:

Ви можете створити такий клас, як наведений нижче код, і використовувати метод запуску і зупинки цього класу до і після розділу коду, ви хочете виміряти витрачений час.

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

}

Дякую.


1
Хоча це посилання може відповісти на питання, краще включити сюди суттєві частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться.
AS Макей

Дякуємо @ASMackay за вашу пропозицію. Я повністю з вами згоден.
Сукрити Саркар
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.