Làm thế nào để tôi có thời gian thực hiện một phương thức trong Java?


834
  1. Làm thế nào để tôi có được thời gian thực hiện của một phương thức?
  2. Có một Timerlớp tiện ích cho những thứ như thời gian một nhiệm vụ mất bao lâu, vv?

Hầu hết các tìm kiếm trên Google trả về kết quả cho bộ tính giờ lên lịch các luồng và tác vụ, đó không phải là điều tôi muốn.


API JAMon là API Java miễn phí, đơn giản, hiệu suất cao, an toàn cho chuỗi, cho phép các nhà phát triển dễ dàng theo dõi hiệu suất và khả năng mở rộng của các ứng dụng sản xuất. JAMon theo dõi lượt truy cập, thời gian thực hiện (tổng, avg, min, max, std dev), v.v. http://jamonapi.sourceforge.net/ tải xuống: http://sourceforge.net/project/showfiles.php?group_id=96550
Mike Pone

1
Bạn cũng có thể muốn xem lớp Đồng hồ bấm giờ Apache Commons Lang . Một lớp tiện ích đơn giản nhưng hữu ích.


Vâng, StopWatch là tuyệt vời cho việc này.
Shubham Pandey

Java 8 sử dụng Instantlớp: stackoverflow.com/a/30975902/1216775
akhil_mittal

Câu trả lời:


1207

Luôn có cách thức lỗi thời:

long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();

long duration = (endTime - startTime);  //divide by 1000000 to get milliseconds.

233
thực ra, "kiểu mới" của nó bởi vì bạn đã sử dụng nanoTime, thứ không được thêm vào cho đến java5
John Gardner

11
Điều này (hoặc sử dụng System.cienTimeMillis ()) dường như là cách nó thường được thực hiện trong Java ... dù sao tôi cũng đã thấy. Nó vẫn nhẹ nhàng làm tôi ngạc nhiên rằng không có lớp tích hợp sẵn, như Timer t = new Timer (); Chuỗi s = t.getElapsed (định dạng); v.v ...
Ogre Psalm33

18
nanoTime không đảm bảo độ chính xác tốt hơn currentTimeMillis (), mặc dù nó thường như vậy. forums.sun.com/thread.jspa?messageID=9460663simongbrown.com/blog/2007/08/20/...
James Schek

10
Tất nhiên, điều quan trọng là luôn nhớ những cạm bẫy của điểm chuẩn vi mô, chẳng hạn như tối ưu hóa trình biên dịch / JVM có thể làm sai lệch kết quả = 8-)
Yuval

18
Không cần phải chặn cuối cùng vì endTime sẽ không được sử dụng nếu ném ngoại lệ.
Peter Lawrey

197

Tôi đi với câu trả lời đơn giản. Làm việc cho tôi.

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

System.out.println("That took " + (endTime - startTime) + " milliseconds");

Nó hoạt động khá tốt. Độ phân giải rõ ràng chỉ đến một phần nghìn giây, bạn có thể làm tốt hơn với System.nanoTime (). Có một số hạn chế cho cả hai (lát lịch trình hệ điều hành, v.v.) nhưng điều này hoạt động khá tốt.

Trung bình trên một vài lần chạy (càng nhiều càng tốt) và bạn sẽ có một ý tưởng hay.


51
Trên thực tế, System.cienTimeMillis () chỉ chính xác trên 15ms. Đối với các giá trị thực sự thấp, nó không thể được tin cậy. Giải pháp cho việc này (như đã đề cập) là System.nanoTime ();
Steve g

Ok, tôi đã chấp nhận đây là câu trả lời chính thức cho đến khi tôi đọc bình luận của Steve g. Tidbit tuyệt vời, Steve!
Ogre Psalm33

4
nanoTime () không đảm bảo độ chính xác tốt hơn currentTimeMillis, nhưng nhiều triển khai JVM có độ chính xác tốt hơn với nanoTime.
James Schek

5
@JamesSchek Bạn thực sự cần phải xem từ ngữ của bạn, như tôi đã đề cập đến nhận xét giống hệt này ở nơi khác; nanoTimeđược đảm bảo ít nhất là kiên quyết như currentTimeMillis. docs.oracle.com/javase/7/docs/api/java/lang/ triệt
b1nary.atr0phy

Một lợi thế nhỏ của currentTimeMillisnó là đó là dấu thời gian thực tế và cũng có thể được sử dụng để ghi lại thời gian bắt đầu / kết thúc, trong khi nanoTime"chỉ có thể được sử dụng để đo thời gian trôi qua và không liên quan đến bất kỳ khái niệm nào khác về thời gian của hệ thống hoặc đồng hồ treo tường . "
Công viên Brad

177

Cố lên các bạn! Không ai đề cập đến cách ổi để làm điều đó (được cho là tuyệt vời):

import com.google.common.base.Stopwatch;

Stopwatch timer = Stopwatch.createStarted();
//method invocation
LOG.info("Method took: " + timer.stop());

Điều tuyệt vời là Stopwatch.toString () thực hiện tốt việc chọn đơn vị thời gian để đo lường. Tức là nếu giá trị nhỏ, nó sẽ tạo ra 38 ns, nếu dài, nó sẽ hiển thị 5m 3 giây

Thậm chí đẹp hơn:

Stopwatch timer = Stopwatch.createUnstarted();
for (...) {
   timer.start();
   methodToTrackTimeFor();
   timer.stop();
   methodNotToTrackTimeFor();
}
LOG.info("Method took: " + timer);

Lưu ý: Google Guava yêu cầu Java 1.6+


21
Thật không may, Đồng hồ bấm giờ của Guava không an toàn cho chủ đề. Tôi học được điều này một cách khó khăn.
Dexter Legaspi

6
@DexterLegaspi Sẽ rất thích thú với trải nghiệm của bạn! Quan tâm chia sẻ?
Siddhartha

1
Sử dụng đồng hồ bấm giờ song song sẽ dẫn đến việc bạn gọi start()nhiều lần liên tiếp (tương tự cho stop()).
Mingwei Samuel

141

Sử dụng InstantThời lượng từ API mới của Java 8,

Instant start = Instant.now();
Thread.sleep(5000);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

đầu ra,

PT5S

2
Cảm ơn, Làm thế nào tôi có thể xuất kết quả mà không có PT ở phía trước?
java123999

1
Vấn đề với phương pháp là Instant không có vấn đề về độ chính xác milli và nano giây. Tham chiếu: stackoverflow.com/questions/20689055/
Mạnh

8
@ java123999: Bạn có thể gọi Duration.between(start, end).getSeconds(). Durationcũng có các phương thức để chuyển đổi sang các đơn vị thời gian khác, ví dụ như toMillis()chuyển đổi thành mili giây.
Emil Lunde

100

Tập hợp tất cả các cách có thể cùng nhau vào một nơi.

Ngày

Date startDate = Calendar.getInstance().getTime();
long d_StartTime = new Date().getTime();
Thread.sleep(1000 * 4);
Date endDate = Calendar.getInstance().getTime();
long d_endTime = new Date().getTime();
System.out.format("StartDate : %s, EndDate : %s \n", startDate, endDate);
System.out.format("Milli = %s, ( D_Start : %s, D_End : %s ) \n", (d_endTime - d_StartTime),d_StartTime, d_endTime);

Hệ thống. currentTimeMillis ()

long startTime = System.currentTimeMillis();
Thread.sleep(1000 * 4);
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime);  
System.out.format("Milli = %s, ( S_Start : %s, S_End : %s ) \n", duration, startTime, endTime );
System.out.println("Human-Readable format : "+millisToShortDHMS( duration ) );

Định dạng có thể đọc được của con người

public static String millisToShortDHMS(long duration) {
    String res = "";    // java.util.concurrent.TimeUnit;
    long days       = TimeUnit.MILLISECONDS.toDays(duration);
    long hours      = TimeUnit.MILLISECONDS.toHours(duration) -
                      TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
    long minutes    = TimeUnit.MILLISECONDS.toMinutes(duration) -
                      TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
    long seconds    = TimeUnit.MILLISECONDS.toSeconds(duration) -
                      TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
    long millis     = TimeUnit.MILLISECONDS.toMillis(duration) - 
                      TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration));

    if (days == 0)      res = String.format("%02d:%02d:%02d.%04d", hours, minutes, seconds, millis);
    else                res = String.format("%dd %02d:%02d:%02d.%04d", days, hours, minutes, seconds, millis);
    return res;
}

Quả ổi: Google Đồng hồ bấm giờ JAR «Một đối tượng của Đồng hồ bấm giờ là đo thời gian trôi qua tính bằng nano giây.

com.google.common.base.Stopwatch g_SW = Stopwatch.createUnstarted();
g_SW.start();
Thread.sleep(1000 * 4);
g_SW.stop();
System.out.println("Google StopWatch  : "+g_SW);

Apache Commons Lang JAR « StopWatch cung cấp API thuận tiện cho việc định thời gian.

org.apache.commons.lang3.time.StopWatch sw = new StopWatch();
sw.start();     
Thread.sleep(1000 * 4);     
sw.stop();
System.out.println("Apache StopWatch  : "+ millisToShortDHMS(sw.getTime()) );

JODA -TIME

public static void jodaTime() throws InterruptedException, ParseException{
    java.text.SimpleDateFormat ms_SDF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
    String start = ms_SDF.format( new Date() ); // java.util.Date

    Thread.sleep(10000);

    String end = ms_SDF.format( new Date() );       
    System.out.println("Start:"+start+"\t Stop:"+end);

    Date date_1 = ms_SDF.parse(start);
    Date date_2 = ms_SDF.parse(end);        
    Interval interval = new org.joda.time.Interval( date_1.getTime(), date_2.getTime() );
    Period period = interval.toPeriod(); //org.joda.time.Period

    System.out.format("%dY/%dM/%dD, %02d:%02d:%02d.%04d \n", 
        period.getYears(), period.getMonths(), period.getDays(),
        period.getHours(), period.getMinutes(), period.getSeconds(), period.getMillis());
}

API thời gian ngày Java từ Java 8 «Một đối tượng Thời lượng biểu thị một khoảng thời gian giữa hai đối tượng Instant .

Instant start = java.time.Instant.now();
    Thread.sleep(1000);
Instant end = java.time.Instant.now();
Duration between = java.time.Duration.between(start, end);
System.out.println( between ); // PT1.001S
System.out.format("%dD, %02d:%02d:%02d.%04d \n", between.toDays(),
        between.toHours(), between.toMinutes(), between.getSeconds(), between.toMillis()); // 0D, 00:00:01.1001 

Spring Framework cung cấplớp tiện ích StopWatch để đo thời gian đã trôi qua trong Java.

StopWatch sw = new org.springframework.util.StopWatch();
sw.start("Method-1"); // Start a named task
    Thread.sleep(500);
sw.stop();

sw.start("Method-2");
    Thread.sleep(300);
sw.stop();

sw.start("Method-3");
    Thread.sleep(200);
sw.stop();

System.out.println("Total time in milliseconds for all tasks :\n"+sw.getTotalTimeMillis());
System.out.println("Table describing all tasks performed :\n"+sw.prettyPrint());

System.out.format("Time taken by the last task : [%s]:[%d]", 
        sw.getLastTaskName(),sw.getLastTaskTimeMillis());

System.out.println("\n Array of the data for tasks performed « Task Name: Time Taken");
TaskInfo[] listofTasks = sw.getTaskInfo();
for (TaskInfo task : listofTasks) {
    System.out.format("[%s]:[%d]\n", 
            task.getTaskName(), task.getTimeMillis());
}

Ra ngoài:

Total time in milliseconds for all tasks :
999
Table describing all tasks performed :
StopWatch '': running time (millis) = 999
-----------------------------------------
ms     %     Task name
-----------------------------------------
00500  050%  Method-1
00299  030%  Method-2
00200  020%  Method-3

Time taken by the last task : [Method-3]:[200]
 Array of the data for tasks performed « Task Name: Time Taken
[Method-1]:[500]
[Method-2]:[299]
[Method-3]:[200]

Đồng hồ bấm giờ của Guava, Apache Commons và Spring Framework không an toàn. Không an toàn cho sử dụng sản xuất.
Deepak Puthraya

@DeepakPuthraya thì sử dụng thư viện nào an toàn cho sử dụng sản xuất?
gaurav

1
@DeepakPuthraya bạn có thể sử dụng API thời gian Java được cung cấp java 8. Mà đơn giản.
Yash

IMO bài đăng này sẽ có lợi nếu mọi giải pháp cũng sẽ hiển thị đầu ra của hệ thống bên ngoài.
BAERUS

87

Sử dụng một trình lược tả (JProfiler, Netbeans Profiler, Visual VM, Eclipse Profiler, v.v.). Bạn sẽ nhận được kết quả chính xác nhất và ít xâm phạm nhất. Họ sử dụng cơ chế JVM tích hợp để định hình, cũng có thể cung cấp cho bạn thông tin bổ sung như dấu vết ngăn xếp, đường dẫn thực thi và kết quả toàn diện hơn nếu cần.

Khi sử dụng một trình lược tả tích hợp đầy đủ, nó rất đơn giản để cấu hình một phương thức. Nhấp chuột phải, Profiler -> Thêm vào Phương thức gốc. Sau đó chạy trình hồ sơ giống như bạn đang chạy thử nghiệm hoặc trình gỡ lỗi.


Đây cũng là một gợi ý tuyệt vời và là một trong những khoảnh khắc bóng đèn "duh" đối với tôi khi tôi đọc câu trả lời này. Dự án của chúng tôi sử dụng JDeveloper, nhưng tôi đã kiểm tra, và chắc chắn, nó có một trình tạo hồ sơ tích hợp!
Ogre Psalm33

2
Từ java 7 build 40 (tôi nghĩ), họ đã bao gồm Trình ghi chuyến bay cũ của JRockits cho java (tìm kiếm Điều khiển nhiệm vụ Java)
Niels Bech Nielsen


Ví dụ, làm thế nào để có được sự thực thi của phương thức trong Java bằng Visual VM?
okwap

41

Đây có lẽ không phải là những gì bạn muốn tôi nói, nhưng đây là một cách sử dụng tốt AOP. Đánh đòn chặn proxy xung quanh phương thức của bạn và thực hiện thời gian trong đó.

Đáng buồn là, tại sao và như thế nào về AOP lại vượt quá phạm vi của câu trả lời này, thật đáng buồn, nhưng đó là cách tôi có thể làm điều đó.

Chỉnh sửa: Đây là một liên kết đến Spring AOP để giúp bạn bắt đầu, nếu bạn quan tâm. Đây là cách triển khai AOP dễ tiếp cận nhất mà Iive bắt gặp đối với java.

Ngoài ra, với những gợi ý rất đơn giản của mọi người khác, tôi nên thêm rằng AOP dành cho khi bạn không muốn những thứ như thời gian xâm chiếm mã của mình. Nhưng trong nhiều trường hợp, cách tiếp cận đơn giản và dễ dàng đó là tốt.


3
Dưới đây là hướng dẫn về cách thực hiện việc này với Spring: veerasundar.com/blog/2010/01/ Khăn
David Tinker

39

System.currentTimeMillis();KHÔNG phải là một cách tiếp cận tốt để đo hiệu suất của các thuật toán của bạn. Nó đo tổng thời gian bạn trải nghiệm khi người dùng xem màn hình máy tính. Nó cũng bao gồm thời gian sử dụng bởi mọi thứ khác đang chạy trên máy tính của bạn trong nền. Điều này có thể tạo ra một sự khác biệt lớn trong trường hợp bạn có rất nhiều chương trình đang chạy trên máy trạm của bạn.

Cách tiếp cận đúng là sử dụng java.lang.managementgói.

Từ http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking trang web:

  • "Thời gian người dùng" là thời gian dành để chạy mã riêng của ứng dụng của bạn.
  • "Thời gian hệ thống" là thời gian dành cho việc chạy mã hệ điều hành thay mặt cho ứng dụng của bạn (chẳng hạn như đối với I / O).

getCpuTime() phương pháp cung cấp cho bạn tổng của những người:

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

public class CPUUtils {

    /** Get CPU time in nanoseconds. */
    public static long getCpuTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadCpuTime( ) : 0L;
    }

    /** Get user time in nanoseconds. */
    public static long getUserTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadUserTime( ) : 0L;
    }

    /** Get system time in nanoseconds. */
    public static long getSystemTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            (bean.getCurrentThreadCpuTime( ) - bean.getCurrentThreadUserTime( )) : 0L;
    }

}

4
Đây chắc chắn là một điểm tốt, rằng "thời gian của người dùng" (thời gian đồng hồ treo tường) không phải lúc nào cũng là thước đo hiệu suất tuyệt vời, đặc biệt là trong một chương trình đa luồng.
Ogre Psalm33

Đây là câu trả lời tôi đang tìm kiếm.
ZhaoGang

30

Với Java 8, bạn cũng có thể làm một cái gì đó như thế này với mọi phương thức bình thường :

Object returnValue = TimeIt.printTime(() -> methodeWithReturnValue());
//do stuff with your returnValue

với TimeIt như:

public class TimeIt {

public static <T> T printTime(Callable<T> task) {
    T call = null;
    try {
        long startTime = System.currentTimeMillis();
        call = task.call();
        System.out.print((System.currentTimeMillis() - startTime) / 1000d + "s");
    } catch (Exception e) {
        //...
    }
    return call;
}
}

Với methode này, bạn có thể thực hiện đo thời gian dễ dàng ở bất cứ đâu trong mã của mình mà không phá vỡ nó. Trong ví dụ đơn giản này tôi chỉ in thời gian. Bạn có thể thêm một Switch cho TimeIt, ví dụ: chỉ in thời gian trong DebugMode hoặc một cái gì đó.

Nếu bạn đang làm việc với Hàm, bạn có thể làm một số thứ như thế này:

Function<Integer, Integer> yourFunction= (n) -> {
        return IntStream.range(0, n).reduce(0, (a, b) -> a + b);
    };

Integer returnValue = TimeIt.printTime2(yourFunction).apply(10000);
//do stuff with your returnValue

public static <T, R> Function<T, R> printTime2(Function<T, R> task) {
    return (t) -> {
        long startTime = System.currentTimeMillis();
        R apply = task.apply(t);
        System.out.print((System.currentTimeMillis() - startTime) / 1000d
                + "s");
        return apply;
    };
}

Điều này có vẻ tốt hơn nhiều so với các giải pháp khác. Nó gần với Spring AOP nhưng nhẹ hơn thế. Đúng 8 cách java! +1 Cảm ơn!
Amit Kumar

Có lẽ điều này có vẻ tốt với bạn, bởi vì Stefan đang sử dụng các hàm java mới lạ mắt. Nhưng tôi nghĩ rằng đây là khó khăn để đọc và hiểu.
Mèo Tonerpson

18

Ngoài ra Chúng ta có thể sử dụng lớp StopWatch của Apache commons để đo thời gian.

Mã mẫu

org.apache.commons.lang.time.StopWatch sw = new org.apache.commons.lang.time.StopWatch();

System.out.println("getEventFilterTreeData :: Start Time : " + sw.getTime());
sw.start();

// Method execution code

sw.stop();
System.out.println("getEventFilterTreeData :: End Time : " + sw.getTime());

15

Chỉ là một bước ngoặt nhỏ, nếu bạn không sử dụng công cụ và muốn thời gian thực hiện với thời gian thực hiện thấp: thực hiện nhiều lần, mỗi lần nhân đôi số lần thực hiện cho đến khi bạn đạt được một giây hoặc lâu hơn. Do đó, thời gian của Cuộc gọi đến System.nanoTime, v.v., cũng như độ chính xác của System.nanoTime không ảnh hưởng nhiều đến kết quả.

    int runs = 0, runsPerRound = 10;
    long begin = System.nanoTime(), end;
    do {
        for (int i=0; i<runsPerRound; ++i) timedMethod();
        end = System.nanoTime();
        runs += runsPerRound;
        runsPerRound *= 2;
    } while (runs < Integer.MAX_VALUE / 2 && 1000000000L > end - begin);
    System.out.println("Time for timedMethod() is " + 
        0.000000001 * (end-begin) / runs + " seconds");

Tất nhiên, hãy cẩn thận khi sử dụng đồng hồ treo tường: ảnh hưởng của quá trình biên dịch JIT, nhiều luồng / quy trình, v.v. Vì vậy, trước tiên bạn cần thực hiện phương thức rất nhiều lần, để trình biên dịch JIT thực hiện công việc của nó, sau đó lặp lại thử nghiệm này nhiều lần và mất thời gian thực hiện thấp nhất.


13

Chúng tôi đang sử dụng các chú thích AspectJ và Java cho mục đích này. Nếu chúng ta cần biết thời gian thực hiện cho một phương thức, chúng ta đơn giản chú thích nó. Phiên bản nâng cao hơn có thể sử dụng cấp độ nhật ký riêng có thể bật và tắt khi chạy.

public @interface Trace {
  boolean showParameters();
}

@Aspect
public class TraceAspect {
  [...]
  @Around("tracePointcut() && @annotation(trace) && !within(TraceAspect)")
  public Object traceAdvice ( ProceedingJintPoint jP, Trace trace ) {

    Object result;
    // initilize timer

    try { 
      result = jp.procced();
    } finally { 
      // calculate execution time 
    }

    return result;
  }
  [...]
}

13

JEP 230: Microbenchmark Suite

FYI, JEP 230: Microbenchmark Suite là một dự án OpenJDK nhằm:

Thêm một bộ microbenchmark cơ bản vào mã nguồn JDK và giúp các nhà phát triển dễ dàng chạy các microbenchmark hiện có và tạo các mã mới.

Tính năng này đã có trong Java 12 .

Khai thác vi sinh vật Java (JMH)

Đối với các phiên bản trước của Java, hãy xem dự án Java Microbenchmark Mining (JMH) dựa trên JEP 230.


11

Mã thực sự tốt.

http://www.rgagnon.com/javadetails/java-0585.html

import java.util.concurrent.TimeUnit;

long startTime = System.currentTimeMillis();
........
........
........
long finishTime = System.currentTimeMillis();

String diff = millisToShortDHMS(finishTime - startTime);


  /**
   * converts time (in milliseconds) to human-readable format
   *  "<dd:>hh:mm:ss"
   */
  public static String millisToShortDHMS(long duration) {
    String res = "";
    long days  = TimeUnit.MILLISECONDS.toDays(duration);
    long hours = TimeUnit.MILLISECONDS.toHours(duration)
                   - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
    long minutes = TimeUnit.MILLISECONDS.toMinutes(duration)
                     - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
    long seconds = TimeUnit.MILLISECONDS.toSeconds(duration)
                   - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
    if (days == 0) {
      res = String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }
    else {
      res = String.format("%dd%02d:%02d:%02d", days, hours, minutes, seconds);
    }
    return res;
  }

3
Trên thực tế, câu hỏi là làm thế nào để tính lượng thời gian mà một phương thức sử dụng, chứ không phải làm thế nào để định dạng nó. Tuy nhiên câu hỏi này khá cũ (gần bốn năm!). Cố gắng tránh hồi sinh các chủ đề cũ trừ khi phản hồi sẽ thêm một cái gì đó mới và có ý nghĩa vào các phản hồi hiện có.
Leigh

1
Và để thêm phần còn lại vào cuối, hãy thực hiện các thay đổi sau: long millis = TimeUnit.MILLISECONDS.toMillis(duration) - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration)); if (days == 0) { res = String.format("%02d:%02d:%02d.%02d", hours, minutes, seconds, millis); } else { res = String.format("%dd%02d:%02d:%02d.%02d", days, hours, minutes, seconds, millis); }
Rick Barkhouse

10

Bạn có thể sử dụng Perf4j . Tiện ích rất tuyệt. Cách sử dụng rất đơn giản

String watchTag = "target.SomeMethod";
StopWatch stopWatch = new LoggingStopWatch(watchTag);
Result result = null; // Result is a type of a return value of a method
try {
    result = target.SomeMethod();
    stopWatch.stop(watchTag + ".success");
} catch (Exception e) {
    stopWatch.stop(watchTag + ".fail", "Exception was " + e);
    throw e; 
}

Thông tin thêm có thể được tìm thấy trong Hướng dẫn dành cho nhà phát triển

Chỉnh sửa: Dự án dường như đã chết


1
Perf4j cũng có thể tạo ra số liệu thống kê tốt đẹp .
Paaske

8
new Timer(""){{
    // code to time 
}}.timeMe();



public class Timer {

    private final String timerName;
    private long started;

    public Timer(String timerName) {
        this.timerName = timerName;
        this.started = System.currentTimeMillis();
    }

    public void timeMe() {
        System.out.println(
        String.format("Execution of '%s' takes %dms.", 
                timerName, 
                started-System.currentTimeMillis()));
    }

}

1
Cuộn lớp đơn giản của riêng bạn là một lựa chọn tốt khi bạn đã thiết lập hệ thống xây dựng và OTS phụ thuộc và không muốn bận tâm đến việc kéo gói OTS khác bao gồm lớp hẹn giờ tiện ích.
Ogre Psalm33

7

Về cơ bản tôi thực hiện các biến thể của điều này, nhưng xem xét cách thức biên dịch hotspot hoạt động, nếu bạn muốn có kết quả chính xác, bạn cần bỏ qua một vài phép đo đầu tiên và đảm bảo rằng bạn đang sử dụng phương pháp trong ứng dụng trong thế giới thực (đọc ứng dụng cụ thể).

Nếu JIT quyết định biên dịch nó, số của bạn sẽ thay đổi rất nhiều. vì vậy hãy chú ý


7

Sử dụng AOP / AspectJ và @Loggablechú thích từ jcabi - các khía cạnh bạn có thể thực hiện dễ dàng và gọn nhẹ:

@Loggable(Loggable.DEBUG)
public String getSomeResult() {
  // return some value
}

Mỗi cuộc gọi đến phương thức này sẽ được gửi đến cơ sở ghi nhật ký SLF4J với DEBUGmức ghi nhật ký. Và mỗi thông điệp tường trình sẽ bao gồm thời gian thực hiện.


7

Spring cung cấp một lớp tiện ích org.springframework.util.StopWatch , theo JavaDoc:

Đồng hồ bấm giờ đơn giản, cho phép tính thời gian của một số tác vụ, hiển thị tổng thời gian chạy và thời gian chạy cho từng tác vụ được đặt tên.

Sử dụng:

StopWatch stopWatch = new StopWatch("Performance Test Result");

stopWatch.start("Method 1");
doSomething1();//method to test
stopWatch.stop();

stopWatch.start("Method 2");
doSomething2();//method to test
stopWatch.stop();

System.out.println(stopWatch.prettyPrint());

Đầu ra:

StopWatch 'Performance Test Result': running time (millis) = 12829
-----------------------------------------
ms     %     Task name
-----------------------------------------
11907  036%  Method 1
00922  064%  Method 2

Với các khía cạnh:

@Around("execution(* my.package..*.*(..))")
public Object logTime(ProceedingJoinPoint joinPoint) throws Throwable {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    Object retVal = joinPoint.proceed();
    stopWatch.stop();
    log.info(" execution time: " + stopWatch.getTotalTimeMillis() + " ms");
    return retVal;
}

Có thể sử dụng điều này với AspectJ?
zygimantus

7

Tôi đã viết một phương thức để in thời gian thực hiện phương thức ở dạng dễ đọc hơn. Ví dụ, để tính giai thừa của 1 triệu, phải mất khoảng 9 phút. Vì vậy, thời gian thực hiện được in là:

Execution Time: 9 Minutes, 36 Seconds, 237 MicroSeconds, 806193 NanoSeconds

Mã ở đây:

public class series
{
    public static void main(String[] args)
    {
        long startTime = System.nanoTime();

        long n = 10_00_000;
        printFactorial(n);

        long endTime = System.nanoTime();
        printExecutionTime(startTime, endTime);

    }

    public static void printExecutionTime(long startTime, long endTime)
    {
        long time_ns = endTime - startTime;
        long time_ms = TimeUnit.NANOSECONDS.toMillis(time_ns);
        long time_sec = TimeUnit.NANOSECONDS.toSeconds(time_ns);
        long time_min = TimeUnit.NANOSECONDS.toMinutes(time_ns);
        long time_hour = TimeUnit.NANOSECONDS.toHours(time_ns);

        System.out.print("\nExecution Time: ");
        if(time_hour > 0)
            System.out.print(time_hour + " Hours, ");
        if(time_min > 0)
            System.out.print(time_min % 60 + " Minutes, ");
        if(time_sec > 0)
            System.out.print(time_sec % 60 + " Seconds, ");
        if(time_ms > 0)
            System.out.print(time_ms % 1E+3 + " MicroSeconds, ");
        if(time_ns > 0)
            System.out.print(time_ns % 1E+6 + " NanoSeconds");
    }
}

6

Có một vài cách để làm điều đó. Tôi thường quay trở lại chỉ sử dụng một cái gì đó như thế này:

long start = System.currentTimeMillis();
// ... do something ...
long end = System.currentTimeMillis();

hoặc điều tương tự với System.nanoTime ();

Đối với một cái gì đó nhiều hơn về mặt điểm chuẩn của mọi thứ dường như cũng có cái này: http://jetm.void.fm/ Chưa bao giờ thử nó mặc dù.


6

Bạn có thể sử dụng thư viện Metrics cung cấp các dụng cụ đo khác nhau. Thêm phụ thuộc:

<dependencies>
    <dependency>
        <groupId>io.dropwizard.metrics</groupId>
        <artifactId>metrics-core</artifactId>
        <version>${metrics.version}</version>
    </dependency>
</dependencies>

Và cấu hình nó cho môi trường của bạn.

Các phương thức có thể được chú thích bằng @Timed :

@Timed
public void exampleMethod(){
    // some code
}

hoặc đoạn mã được gói bằng Timer :

final Timer timer = metricsRegistry.timer("some_name");
final Timer.Context context = timer.time();
// timed code
context.stop();

Số liệu tổng hợp có thể xuất sang bảng điều khiển, JMX, CSV hoặc khác.

@Timed ví dụ đầu ra số liệu:

com.example.ExampleService.exampleMethod
             count = 2
         mean rate = 3.11 calls/minute
     1-minute rate = 0.96 calls/minute
     5-minute rate = 0.20 calls/minute
    15-minute rate = 0.07 calls/minute
               min = 17.01 milliseconds
               max = 1006.68 milliseconds
              mean = 511.84 milliseconds
            stddev = 699.80 milliseconds
            median = 511.84 milliseconds
              75% <= 1006.68 milliseconds
              95% <= 1006.68 milliseconds
              98% <= 1006.68 milliseconds
              99% <= 1006.68 milliseconds
            99.9% <= 1006.68 milliseconds

5

Nếu bạn muốn đồng hồ treo tường

long start_time = System.currentTimeMillis();
object.method();
long end_time = System.currentTimeMillis();
long execution_time = end_time - start_time;

5

Như "skaffman" đã nói, sử dụng AOP HOẶC bạn có thể sử dụng chế độ dệt mã byte thời gian chạy, giống như các công cụ bao phủ phương pháp thử nghiệm đơn vị sử dụng để thêm thông tin thời gian vào các phương thức được gọi một cách trong suốt.

Bạn có thể xem mã được sử dụng bởi các công cụ công cụ nguồn mở như Emma ( http://doads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime=1118607545&big_mirror=0 ). Công cụ bảo hiểm mã nguồn mở khác là http://prdoads.sourceforge.net/cobertura/cobertura-1.9-src.zip?doad .

Nếu cuối cùng bạn quản lý để làm những gì bạn đặt ra, xin vui lòng. chia sẻ lại với cộng đồng ở đây với nhiệm vụ / lọ kiến ​​của bạn.


4
long startTime = System.currentTimeMillis();
// code goes here
long finishTime = System.currentTimeMillis();
long elapsedTime = finishTime - startTime; // elapsed time in milliseconds

4

Tôi đã sửa đổi mã từ câu trả lời đúng để có kết quả sau vài giây:

long startTime = System.nanoTime();

methodCode ...

long endTime = System.nanoTime();
double duration = (double)(endTime - startTime) / (Math.pow(10, 9));
Log.v(TAG, "MethodName time (s) = " + duration);

4

Bạn có thể sử dụng lớp đồng hồ bấm giờ từ dự án lõi mùa xuân:

Mã số:

StopWatch stopWatch = new StopWatch()
stopWatch.start();  //start stopwatch
// write your function or line of code.
stopWatch.stop();  //stop stopwatch
stopWatch.getTotalTimeMillis() ; ///get total time

Tài liệu cho Đồng hồ bấm giờ: Đồng hồ bấm giờ đơn giản, cho phép định thời gian cho một số tác vụ, hiển thị tổng thời gian chạy và thời gian chạy cho mỗi tác vụ được đặt tên. Che giấu việc sử dụng System.cienTimeMillis (), cải thiện khả năng đọc mã ứng dụng và giảm khả năng xảy ra lỗi tính toán. Lưu ý rằng đối tượng này không được thiết kế để an toàn cho luồng và không sử dụng đồng bộ hóa. Lớp này thường được sử dụng để xác minh hiệu suất trong quá trình chứng minh và phát triển, chứ không phải là một phần của các ứng dụng sản xuất.


3

Bạn có thể thử cách này nếu chỉ muốn biết thời gian.

long startTime = System.currentTimeMillis();
//@ Method call
System.out.println("Total time [ms]: " + (System.currentTimeMillis() - startTime));    

3

Ok, đây là một lớp đơn giản được sử dụng cho thời gian đơn giản của các chức năng của bạn. Có một ví dụ dưới đây.

public class Stopwatch {
    static long startTime;
    static long splitTime;
    static long endTime;

    public Stopwatch() {
        start();
    }

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

    public void split() {
        split("");
    }

    public void split(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Split time for [" + tag + "]: " + (endTime - splitTime) + " ms");
        splitTime = endTime;
    }

    public void end() {
        end("");
    }
    public void end(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Final time for [" + tag + "]: " + (endTime - startTime) + " ms");
    }
}

Mẫu sử dụng:

public static Schedule getSchedule(Activity activity_context) {
        String scheduleJson = null;
        Schedule schedule = null;
/*->*/  Stopwatch stopwatch = new Stopwatch();

        InputStream scheduleJsonInputStream = activity_context.getResources().openRawResource(R.raw.skating_times);
/*->*/  stopwatch.split("open raw resource");

        scheduleJson = FileToString.convertStreamToString(scheduleJsonInputStream);
/*->*/  stopwatch.split("file to string");

        schedule = new Gson().fromJson(scheduleJson, Schedule.class);
/*->*/  stopwatch.split("parse Json");
/*->*/  stopwatch.end("Method getSchedule"); 
    return schedule;
}

Mẫu đầu ra của bàn điều khiển:

Split time for [file to string]: 672 ms
Split time for [parse Json]: 893 ms
Final time for [get Schedule]: 1565 ms

3

Trong Java 8, một lớp mới có tên Instantđược giới thiệu. Theo tài liệu:

Tức thì đại diện cho sự bắt đầu của một nano giây trên dòng thời gian. Lớp này hữu ích để tạo dấu thời gian để biểu thị thời gian của máy. Phạm vi của một tức thời đòi hỏi lưu trữ một số lớn hơn một số dài. Để đạt được điều này, lớp lưu trữ một epoch giây dài và một int đại diện cho nano giây của giây, sẽ luôn nằm trong khoảng từ 0 đến 999.999.999. Kỷ nguyên giây được đo từ kỷ nguyên Java tiêu chuẩn 1970-01-01T00: 00: 00Z trong đó các giá trị sau kỷ nguyên có giá trị dương và các giá trị trước đó có giá trị âm. Đối với cả phần epoch-giây và nano giây, giá trị lớn hơn luôn nằm sau dòng thời gian hơn giá trị nhỏ hơn.

Điều này có thể được sử dụng như:

Instant start = Instant.now();
try {
    Thread.sleep(7000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

Nó in PT7.001S.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.