2010-04-03 46 views
64

Xin lỗi nếu điều này nghe có vẻ như một câu hỏi câm nhưng làm thế nào để bạn thời gian thực hiện một chương trình java? Tôi không chắc mình nên sử dụng lớp nào để làm điều này.Làm thế nào để thời gian thực hiện chương trình Java tốc độ

tôi là kinda tìm kiếm cái gì đó như:

//Some timer starts here 
for (int i = 0; i < length; i++) { 
    // Do something 
} 
//End timer here 

System.out.println("Total execution time: " + totalExecutionTime); 

Cảm ơn

Trả lời

106
final long startTime = System.currentTimeMillis(); 
for (int i = 0; i < length; i++) { 
    // Do something 
} 
final long endTime = System.currentTimeMillis(); 

System.out.println("Total execution time: " + (endTime - startTime)); 

Hy vọng điều này sẽ hữu ích.

+1

nó thực sự phải là nanoTime thực sự – Eugene

+4

Không nên là nanoTime. Xem câu trả lời của rhu. – fabspro

+3

Có một số lý do cụ thể mà bạn đã sử dụng "cuối cùng" ở đây không? Điều gì sẽ khác nếu bạn từ chối từ khóa đó? – dijxtra

7

Bạn có thể tận dụng System#nanoTime(). Nhận nó trước và sau khi thực hiện và chỉ làm toán. Nó được ưu tiên trên System#currentTimeMillis() vì nó có độ chính xác cao hơn. Tùy thuộc vào phần cứng và nền tảng được sử dụng, bạn có thể nhận được khoảng cách không chính xác trong thời gian đã trôi qua. Ở đây với Core2Duo trên Windows, giữa khoảng 0 và ~ 15ms thực sự không có gì có thể được tính toán.

Công cụ nâng cao hơn là profiler.

+0

Bộ tính giờ trên Windows không có độ phân giải đặc biệt tốt theo mặc định. Có * là * một bộ đếm thời gian hiệu suất cao quá, nhưng nó khó khăn hơn nhiều để sử dụng ngay cả từ C và Java không (AFAIK) cung cấp quyền truy cập vào một mức độ thấp của hackery mà không có một JNI thunk. –

+0

+1 cho liên kết hồ sơ. –

+1

'nanoTime()' có một vấn đề (ít nhất là trên Windows); dấu thời gian cụ thể cho lõi bộ xử lý. Tôi đã có một chương trình có thời gian thực hiện tiêu cực vì nó có dấu thời gian "bắt đầu" trên một lõi và dấu thời gian "dừng" trên lõi khác. – gustafc

6

Bạn nhận được thời gian hệ thống hiện tại, trong mili giây:

final long startTime = System.currentTimeMillis(); 

Sau đó, bạn làm những gì bạn sẽ làm:

for (int i = 0; i < length; i++) { 
    // Do something 
} 

Sau đó, bạn nhìn thấy nó mất bao lâu:

final long elapsedTimeMillis = System.currentTimeMillis() - startTime; 
+0

Câu trả lời của BalusC cũng chính xác; nó phụ thuộc vào độ phân giải hẹn giờ cần thiết, và tại sao bạn cần thời gian. –

1

sử dụng lâu startTime=System.currentTimeMillis() cho thời gian bắt đầu, ở đầu vòng lặp

đặt long endTime= System.currentTimeMillis(); bên ngoài khi kết thúc vòng lặp. Bạn sẽ phải trừ các giá trị để có được thời gian chạy theo mili giây.

Nếu bạn muốn thời gian trong nano giây, hãy kiểm tra System.nanoTime()

0
public class someClass 
{ 
    public static void main(String[] args) // your app start point 
    { 
     long start = java.util.Calendar.getInstance().getTimeInMillis(); 

     ... your stuff ... 

     long end = java.util.Calendar.getInstance().getTimeInMillis(); 
     System.out.println("it took this long to complete this stuff: " + (end - start) + "ms"); 
    } 
} 
29

Hãy nhận biết rằng có một số vấn đề mà System#nanoTime() không thể tin cậy được sử dụng trên đa lõi CPU để ghi lại thời gian trôi qua ... mỗi lõi có lưu giữ các TSC của riêng mình (Time Stamp Counter): bộ đếm này được sử dụng để có được thời gian nano (thực sự nó là số lượng bọ ve kể từ khi CPU khởi động). Do đó, trừ khi hệ điều hành thực hiện một số thời gian TSC để giữ cho lõi đồng bộ, sau đó nếu một luồng được lên lịch một lõi khi đọc lần đầu, sau đó chuyển sang một lõi khác, thời gian tương đối có thể rời rạc xuất hiện để nhảy lùi và tiến lên.

Tôi đã quan sát điều này một thời gian trước đây về AMD/Solaris, nơi thời gian trôi qua giữa hai điểm thời gian đôi khi trở lại dưới dạng giá trị âm hoặc số dương lớn bất ngờ. Đã có một bản vá hạt nhân Solaris và một thiết lập BIOS cần thiết để buộc AMD PowerNow! tắt, xuất hiện để giải quyết nó.

Ngoài ra, có (AFAIK) một lỗi không được sửa đổi đến nay khi sử dụng java System#nanoTime() trong môi trường VirtualBox; gây ra tất cả các loại vấn đề luồng liên tục kỳ lạ đối với chúng tôi vì phần lớn gói java.util.concurrency dựa trên thời gian nano.

Xem thêm:

Is System.nanoTime() completely useless? http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html

+3

+1 để giải thích rõ ràng về những thiếu sót của nanoTime. – Jason

3

Đối với công cụ đơn giản, System.currentTimeMillis() có thể làm việc.

Nó thực sự rất phổ biến mà IDE của tôi là thiết lập để khi vào "t0" nó tạo cho tôi những dòng sau:

final long t0 = System.currentTimeMillis() 

Nhưng đối với những điều phức tạp hơn, có thể bạn sẽ muốn sử dụng phép đo thời gian thống kê , giống như ở đây (di chuyển xuống một chút và nhìn vào các số đo thời gian trình bày bao gồm độ lệch chuẩn vv):

http://perf4j.codehaus.org/devguide.html

+0

+1 để chỉ ra mã trình tạo tự động. Tôi sử dụng một tuyên bố tương tự tất cả các thời gian, và không biết về chèn mẫu mã. Chỉ cần tìm ra cách để làm điều đó với nhật thực, và nó chắc chắn sẽ giúp! – Jason

+0

Tất cả các dịch vụ của Codehaus đã bị chấm dứt. Liên kết của bạn hiện đã bị hỏng. – naXa

0

Bạn cũng có thể thử Perf4J. Đó là một cách gọn gàng để làm những gì bạn đang tìm kiếm và giúp thống kê hiệu suất tổng hợp như trung bình, tối thiểu, tối đa, độ lệch chuẩn và giao dịch mỗi giây trong một khoảng thời gian đã định. Một chiết xuất từ ​​http://perf4j.codehaus.org/devguide.html:

StopWatch stopWatch = new LoggingStopWatch(); 

try { 
    // the code block being timed - this is just a dummy example 
    long sleepTime = (long)(Math.random() * 1000L); 
    Thread.sleep(sleepTime); 
    if (sleepTime > 500L) { 
     throw new Exception("Throwing exception"); 
    } 

    stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms"); 
} catch (Exception e) { 
    stopWatch.stop("codeBlock2.failure", "Exception was: " + e); 
} 

Output:

INFO: start[1230493236109] time[447] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493236719] time[567] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception] 
INFO: start[1230493237286] time[986] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception] 
INFO: start[1230493238273] time[194] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493238467] time[463] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493238930] time[310] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493239241] time[610] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception] 
INFO: start[1230493239852] time[84] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493239937] time[30] tag[codeBlock2.success] message[Sleep time was < 500 ms] 
INFO: start[1230493239968] time[852] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception] 
0

Sử dụng System.currentTimeMillis() là cách thích hợp để làm điều này. Tuy nhiên, nếu bạn sử dụng dòng lệnh và bạn muốn dành toàn bộ thời gian cho chương trình một cách nhanh chóng, hãy suy nghĩ về:

time java App 

cho phép bạn không sửa đổi mã và thời gian ứng dụng của mình.

+0

Điều này phụ thuộc vào cách bạn chạy mã. Nếu đó là một đoạn mã chạy một máy chủ, thì bạn sẽ bao gồm thời gian khởi động không chính xác. –

2

Sử dụng AOP/AspectJ và @Loggable chú thích từ jcabi-aspects bạn có thể làm điều đó dễ dàng và nhỏ gọn:

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

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

Các vấn đề liên quan