2009-04-08 60 views
67

Cách tốt nhất để tính chênh lệch thời gian trong C++ là gì? Tôi đang định thời gian thực hiện tốc độ của một chương trình, vì vậy tôi quan tâm đến mili giây. Tốt hơn, seconds.milliseconds ..Cách tính chênh lệch thời gian trong C++

Câu trả lời được chấp nhận hoạt động, nhưng cần phải bao gồm giờ hoặc thời gian.h như đã nêu trong các nhận xét.

+0

Đợi, nhưng không thể liên kết ngay bây giờ –

+1

Việc bỏ phiếu quá gần, quá muộn. Tôi có một câu trả lời. Rất cố gắng nhưng. Btw, tôi không thể tìm thấy một liên kết. –

+0

Cửa sổ dành cho cửa sổ? sau đó thử GetTickCount (Windows API) –

Trả lời

97

Xem chức năng std::clock().

const clock_t begin_time = clock(); 
// do something 
std::cout << float(clock() - begin_time)/CLOCKS_PER_SEC; 

Nếu bạn muốn tính thời gian thực hiện cho bản thân (không dành cho người dùng), tốt hơn nên làm điều này trong đồng hồ (không giây).

EDIT:
tập tin tiêu đề trách nhiệm - <ctime> hoặc <time.h>

+0

Khi tôi chạy mã này, có được một số lượng lớn, không có ý tưởng nó có nghĩa là gì. Tôi muốn cái gì đó nói "9,34 giây". –

+0

Đừng quên #include hoặc một cách thích hợp để đồng hồ() nhận được một nguyên mẫu thích hợp và clock_t được xác định. – RBerteig

+3

Hãy nhớ rằng mặc dù clock() trả về một số mili giây, độ chính xác của clock() có thể tồi tệ hơn nhiều. Fir instance trong Windows, độ chính xác của hàm clock() là 40 ms. –

5

Chỉ cần một mặt lưu ý: nếu bạn đang chạy trên Windows, và bạn thực sự thực sự cần chính xác, bạn có thể sử dụng QueryPerformanceCounter. Nó cung cấp cho bạn thời gian trong (có khả năng) nano giây.

3

Nhận thời gian hệ thống tính bằng mili giây ở đầu, và một lần nữa ở cuối và trừ.

Để có được số mili giây kể từ năm 1970 trong POSIX bạn sẽ viết:

struct timeval tv; 

gettimeofday(&tv, NULL); 
return ((((unsigned long long)tv.tv_sec) * 1000) + 
     (((unsigned long long)tv.tv_usec)/1000)); 

Để có được số mili giây kể từ năm 1601 trên Windows bạn sẽ viết:

SYSTEMTIME systime; 
FILETIME filetime; 

GetSystemTime(&systime); 
if (!SystemTimeToFileTime(&systime, &filetime)) 
    return 0; 

unsigned long long ns_since_1601; 
ULARGE_INTEGER* ptr = (ULARGE_INTEGER*)&ns_since_1601; 

// copy the result into the ULARGE_INTEGER; this is actually 
// copying the result into the ns_since_1601 unsigned long long. 
ptr->u.LowPart = filetime.dwLowDateTime; 
ptr->u.HighPart = filetime.dwHighDateTime; 

// Compute the number of milliseconds since 1601; we have to 
// divide by 10,000, since the current value is the number of 100ns 
// intervals since 1601, not ms. 
return (ns_since_1601/10000); 

Nếu bạn quan tâm đến bình thường hóa câu trả lời của Windows để nó cũng trả về số mili giây kể từ năm 1970, sau đó bạn sẽ phải điều chỉnh câu trả lời của mình theo 11644473600000 mili giây. Nhưng điều đó không cần thiết nếu tất cả những gì bạn quan tâm là thời gian trôi qua.

28

Tôi nghiêm túc xem xét việc sử dụng Boost, đặc biệt là tăng :: posix_time :: ptime và boost :: posix_time :: time_duration (tại http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time.html).

Đa nền tảng, dễ sử dụng và theo kinh nghiệm của tôi cung cấp mức độ phân giải thời gian cao nhất mà hệ điều hành cung cấp. Có thể cũng rất quan trọng; nó cung cấp một số toán tử IO rất đẹp.

Để sử dụng nó để tính toán sự khác biệt trong thực hiện chương trình (để micro; lẽ overkill), nó sẽ giống như thế này [trình duyệt bằng văn bản, chưa được thử nghiệm]:

ptime time_start(microsec_clock::local_time()); 
//... execution goes here ... 
ptime time_end(microsec_clock::local_time()); 
time_duration duration(time_end - time_start); 
cout << duration << '\n'; 
+2

Nhưng boost local_time() là _not_ đơn điệu vì vậy nó không nên được sử dụng để đo thời gian mất. Tôi đã không tìm thấy một cách để truy cập thời gian đơn điệu từ Boost. – gatopeich

6

chỉ trong trường hợp bạn đang ở trên Unix , bạn có thể sử dụng time để có được thời gian thực hiện:

$ g++ myprog.cpp -o myprog 
$ time ./myprog 
11

Trong Windows: sử dụng GetTickCount

//GetTickCount defintition 
#include <windows.h> 
int main() 
{ 

    DWORD dw1 = GetTickCount(); 

    //Do something 

    DWORD dw2 = GetTickCount(); 

    cout<<"Time difference is "<<(dw2-dw1)<<" milliSeconds"<<endl; 

} 
5

Bạn cũng có thể sử dụng clock_gettime.Phương pháp này có thể được sử dụng để đo: rộng

  1. Hệ thống real-time clock
  2. Hệ thống rộng đơn điệu đồng hồ
  3. mỗi Process thời gian CPU
  4. mỗi quá trình thời gian Chủ đề CPU

Mã là như sau:

#include <time.h> 
#include <iostream> 
int main(){ 
    timespec ts_beg, ts_end; 
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_beg); 
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_end); 
    std::cout << (ts_end.tv_sec - ts_beg.tv_sec) + (ts_end.tv_nsec - ts_beg.tv_nsec)/1e9 << " sec"; 
} 

`

13

tăng 1.46.0 và lên bao gồm các thư viện Chrono:

lớp thread_clock cung cấp quyền truy cập vào các chủ đề thực tường đồng hồ, ví dụ: đồng hồ thực CPU thời gian của tiểu trình đang gọi. Các chủ đề liên quan thời điểm hiện tại có thể thu được bằng cách gọi thread_clock :: nay()

#include <boost/chrono/thread_clock.hpp> 
{ 
... 
    using namespace boost::chrono; 
    thread_clock::time_point start = thread_clock::now(); 
    ... 
    thread_clock::time_point stop = thread_clock::now(); 
    std::cout << "duration: " << duration_cast<milliseconds>(stop - start).count() << " ms\n"; 
+7

Ngoài ra, ** C++ 11 ** có không gian tên 'std :: chrono' với hầu như cùng nội dung. – ulidtko

+1

@ulidtko cũng dễ dàng quá http://en.cppreference.com/w/cpp/chrono/duration/duration_cast –

0

Điều này dường như làm việc tốt cho intel Mac 10.7:

#include <time.h> 

time_t start = time(NULL); 


    //Do your work 


time_t end = time(NULL); 
std::cout<<"Execution Time: "<< (double)(end-start)<<" Seconds"<<std::endl; 
+0

bằng mili giây ??? –

27

nếu bạn đang sử dụng C++ 11, đây là một wrapper đơn giản (xem này gist):

#include <iostream> 
#include <chrono> 

class Timer 
{ 
public: 
    Timer() : beg_(clock_::now()) {} 
    void reset() { beg_ = clock_::now(); } 
    double elapsed() const { 
     return std::chrono::duration_cast<second_> 
      (clock_::now() - beg_).count(); } 

private: 
    typedef std::chrono::high_resolution_clock clock_; 
    typedef std::chrono::duration<double, std::ratio<1> > second_; 
    std::chrono::time_point<clock_> beg_; 
}; 

Hoặc cho C++ 03 trên * nix:

#include <iostream> 
#include <ctime> 

class Timer 
{ 
public: 
    Timer() { clock_gettime(CLOCK_REALTIME, &beg_); } 

    double elapsed() { 
     clock_gettime(CLOCK_REALTIME, &end_); 
     return end_.tv_sec - beg_.tv_sec + 
      (end_.tv_nsec - beg_.tv_nsec)/1000000000.; 
    } 

    void reset() { clock_gettime(CLOCK_REALTIME, &beg_); } 

private: 
    timespec beg_, end_; 
}; 

Ví dụ về sử dụng:

int main() 
{ 
    Timer tmr; 
    double t = tmr.elapsed(); 
    std::cout << t << std::endl; 

    tmr.reset(); 
    t = tmr.elapsed(); 
    std::cout << t << std::endl; 
    return 0; 
} 
+2

Một tùy chọn khác sẽ là sử dụng boost :: chrono thay vì C++ 11 STL std :: chrono namespace. Cảm ơn bạn đã viết mã. –

+2

Hoạt động trên Mac OS! Cảm ơn mã của bạn. –

+0

Cẩn thận: Điều này sẽ không hoạt động nếu người dùng thay đổi thời gian của mình giữa 'Timer()' và cuộc gọi thành 'elapsed()' nếu '! Std :: chrono :: high_resolution_clock :: is_steady' - đó là trường hợp trên Linux ! – jhasse

2

Nếu bạn đang sử dụng:

tstart = clock(); 

// ...do something... 

tend = clock(); 

Sau đó, bạn sẽ cần những điều sau đây để có được thời gian trong vài giây:

time = (tend - tstart)/(double) CLOCKS_PER_SEC; 
4

Đối tôi, cách dễ nhất là:

#include <boost/timer.hpp> 

boost::timer t; 
double duration; 

t.restart(); 
/* DO SOMETHING HERE... */ 
duration = t.elapsed(); 

t.restart(); 
/* DO OTHER STUFF HERE... */ 
duration = t.elapsed(); 

sử dụng đoạn mã này bạn không phải thực hiện thao tác cổ điển end - start.

Tận hưởng cách tiếp cận yêu thích của bạn.

+0

là t.elapsed() tính bằng giây hoặc giây-giây? – mkuse

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