มีนาฬิกาจับเวลาใน Java หรือไม่?


107

มีนาฬิกาจับเวลาใน Java หรือไม่? ใน 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/…
Nikita Bosik

คำตอบ:


94

คุณจะพบหนึ่งใน

http://commons.apache.org/lang/

ก็เรียกว่า

org.apache.commons.lang.time.StopWatch

แต่มันก็เหมือนกับของคุณ หากคุณต้องการความแม่นยำมากขึ้นให้ใช้ไฟล์

System.nanoTime()

ดูคำถามนี้ได้ที่นี่:

เวลาวัดค่าโสหุ้ยใน Java


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
นาฬิกาจับเวลา guavas หายgetStartTime()apache หายisRunning()อ่า
ถึง Kra

3
@ToKra คุณจะทำอะไรกับเวลาเริ่มต้นต่อไป? เนื่องจากเป็นเวลานาโนคุณจึงไม่สามารถใช้เพื่อสิ่งที่มีความหมายได้ตามที่อธิบายไว้ในเอกสาร
Trejkaz

1
ตอนนี้คุณใช้สิ่งนี้เพื่อรับมิลลิวินาที: long stopWatch = stopWatch.elapsed (TimeUnit.MILLISECONDS);
PHPGuru

ฝรั่งมันเวอร์ชั่นไหน ฉันใช้ 1.8 แต่ไม่พบคลาสนาฬิกาจับเวลา
Laser Infinite

59

ตอนนี้คุณสามารถลองสิ่งต่างๆเช่น:

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

เอาต์พุตอยู่ใน ISO 8601


1
ง่ายและรวดเร็วขอบคุณมาก! ช่วยติดตามระยะเวลาของงานตั้งแต่เริ่มต้น
ndm13

จะเกิดอะไรขึ้นถ้าคุณเปลี่ยนเวลาของระบบระหว่างการนอนหลับ?
Peteter

1
@Peteter เป็นเพียงตัวอย่างเท่านั้น หากคุณใช้กล่อง linux คุณต้องจัดการกับนาฬิกาฮาร์ดแวร์และนาฬิกาที่มีการจัดการเคอร์เนล หากคุณเปลี่ยนนาฬิกาฮาร์ดแวร์จะไม่มีผลกระทบใด ๆ แต่ในนาฬิกาที่มีการจัดการเคอร์เนลคุณจะมีปัญหา: Instant.now () รับเวลาของระบบและจะแสดงช่วงเวลาที่ไม่ถูกต้อง
Valtoni Boaventura

ฉันไม่รู้ด้วยซ้ำว่ามันทำงานบน Android ได้ สิ่งที่ควรรู้ :)
Valtoni Boaventura

ไม่ลืม java.time.Instant ไม่เปลี่ยนรูปและเธรดปลอดภัย :)
Amos Kosgei

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 () เชื่อมโยงกับวันที่ / เวลาของระบบและไม่รับประกันว่าจะซ้ำซากจำเจ (เช่นคุณอาจได้รับเวลาที่ผ่านไปเป็นลบ)
oligofren

8

รหัสไม่ได้ทำงานเพราะตัวแปรที่ผ่านไปในgetElapsedTimeSecs()ไม่ได้เป็นหรือfloatdouble


7

ไม่มียูทิลิตี้ Stopwatch ในตัว แต่สำหรับ JSR-310 (Java 8 Time) คุณสามารถทำได้ง่ายๆ

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

ฉันไม่ได้เปรียบเทียบสิ่งนี้อย่างถูกต้อง แต่ฉันเดาว่าการใช้นาฬิกาจับเวลาของ Guava จะมีประสิทธิภาพมากกว่า



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 () เชื่อมโยงกับวันที่ / เวลาของระบบและไม่รับประกันว่าจะซ้ำซากจำเจ (เช่นคุณอาจได้รับเวลาที่ผ่านไปเป็นลบ)
oligofren

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 ล่ะ?
Bill Effin Murray

ในกรณีส่วนใหญ่คุณจะใช้ไลบรารีทั่วไปเช่นที่กล่าวถึงในคำตอบอื่น ๆ (เช่น 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()เชื่อมโยงกับวันที่ / เวลาของระบบและไม่รับประกันว่าจะซ้ำซากจำเจ (เช่นคุณอาจได้รับเวลาที่ผ่านไปเป็นลบ)
oligofren

หากคุณตัดสินใจที่จะสร้างของคุณเองเพียงแค่ใช้System.nanoTime()เพื่อให้ได้ผลลัพธ์ที่ถูกต้องเสมอ
oligofren

2

Performetricsมอบคลาสนาฬิกาจับเวลาที่สะดวกสบายในแบบที่คุณต้องการ สามารถวัดเวลานาฬิกาแขวนและอื่น ๆ อีกทั้งยังวัดเวลา CPU (เวลาของผู้ใช้และเวลาของระบบ) หากคุณต้องการ มีขนาดเล็กฟรีและคุณสามารถดาวน์โหลดได้จาก 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 Stopwatch โซลูชั่นการทำงานอย่างเต็มที่

ที่นี่คุณจะได้รับโซลูชันการทำงานอย่างเต็มที่

เพียงตัวอย่างจากโซลูชันที่เชื่อมโยงด้านบน:

คุณสามารถสร้างคลาสเช่นโค้ดด้านล่างและใช้วิธีการเริ่มและหยุดคลาสนี้ก่อนและหลังส่วนโค้ดคุณต้องการวัดเวลาที่ใช้

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 Mackay

ขอบคุณ @ASMackay สำหรับข้อเสนอแนะของคุณ ฉันเห็นด้วยกับคุณ.
Sukriti Sarkar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.