Cách tính chênh lệch múi giờ trong C ++


95

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

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


Dupe, nhưng không thể liên kết ngay bây giờ
Robert Gould

2
Cuộc bỏ phiếu để kết thúc là quá ít, quá muộn. Tôi có một câu trả lời hiệu quả. Rất cố gắng nhưng. Btw, tôi cũng không thể tìm thấy một liên kết.
Jack BeNimble

Của nó cho các cửa sổ? sau đó thử GetTickCount (API Windows)
aJ.

5
Robert: May mắn thay, vì bài đăng mới cho phép nhiều câu trả lời hơn, một trong số đó tôi đã chọn. Nghiêm túc mà nói, tôi đặt câu hỏi về giá trị của việc đóng một bài trùng lặp. Điều gì sẽ xảy ra nếu một số giải pháp không được đề cập trong giải pháp đầu tiên? Các công nghệ mới phát triển? Không thể tìm thấy nó vì các tiêu đề khác nhau?
Jack BeNimble

2
@JackBeNimble đã nhận được một số "lỗi" không phải là lỗi chính xác (có lẽ những người có thể đọc nhanh câu hỏi và đánh dấu nó vì nó nghe giống với một câu hỏi khác), tôi thực sự đồng ý với quan điểm của bạn ... có thể là một điểm để trao đổi chồng meta: o
code_fodder

Câu trả lời:


123

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

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 toán thời gian thực hiện cho chính mình (không phải cho người dùng), tốt hơn nên làm điều này trong tích tắc đồng hồ (không phải giây).

CHỈNH SỬA:
các tệp tiêu đề có trách nhiệm - <ctime>hoặc<time.h>


4
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ể kém hơn nhiều. Cá thể linh sam trong Windows độ chính xác của hàm clock () là 40 ms.
John Dibling

2
Tôi đã thử điều này trên Mac 10.7. ứng dụng của tôi thực thi tệp 100 mb trong 15 giây, nhưng thời gian khác báo cáo là 61 giây. Không sử dụng nhiều. Tôi nghĩ thời gian () có lẽ tốt hơn.
Miek

5
clock()trả về thời gian CPU được tiêu thụ bởi chương trình. Vì vậy, nếu chương trình được chạy trong song song với thời gian trả về bởi các chức năng sẽ được tích lũy trong những thời gian dành cho tất cả CPU, chứ không phải là thời gian trôi qua cplusplus.com/reference/ctime/clock
Ameer Jewdaki

3
Câu trả lời này gây hiểu lầm vì nó hiển thị thời gian CPU, không phải thời gian đồng hồ treo tường thực tế.
Tia cực tím

1
Tôi phải đồng ý với Ultraviolet ở đây, việc sử dụng thời gian CPU để đo tốc độ của một chương trình có vẻ như là một việc làm sai trái. OP nên bỏ đánh dấu đây là câu trả lời đúng. IMO bạn nên sử dụng std :: chrono :: steady_clock :: now () như mô tả của nhiều câu trả lời trong chủ đề sau stackoverflow.com/questions/2808398/easily-measure-elapsed-time
arunsun

37

nếu bạn đang sử dụng c ++ 11, đây là một trình bao bọc đơn giản (xem ý chính này ):

#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 đối với 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ề cách 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ì không gian tên C ++ 11 STL std :: chrono. Cảm ơn bạn cho mã của bạn.
Didac Perez Parera

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()if !std::chrono::high_resolution_clock::is_steady- đó là trường hợp trên Linux!
jhasse

30

Tôi sẽ nghiêm túc xem xét việc sử dụng Boost, đặc biệt là boost :: 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 ).

Nó đa nền tảng, dễ sử dụng và theo kinh nghiệm của tôi cung cấp độ 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 hay.

Để sử dụng nó để tính toán sự khác biệt trong quá trình thực thi chương trình (đến micro giây; có thể là quá mức cần thiết), nó sẽ trông giống như sau [trình duyệt được viết, chưa được kiểm tra]:

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

3
Nhưng boost local_time () không phải là đơn điệu nên không nên dùng nó để đo thời gian trôi đi. Tôi chưa tìm ra cách truy cập thời gian đơn điệu từ Boost.
gatopeich

27

Tôi đã thêm câu trả lời này để làm rõ rằng câu trả lời được chấp nhận hiển thị thời gian CPU có thể không phải là thời gian bạn muốn. Vì theo tham khảo thì có thời gian CPU và thời gian đồng hồ treo tường . Thời gian đồng hồ treo tường là thời gian hiển thị thời gian thực tế đã trôi qua bất kể điều kiện nào khác như CPU ​​được chia sẻ bởi các quy trình khác. Ví dụ: tôi đã sử dụng nhiều bộ xử lý để thực hiện một tác vụ nhất định và thời gian CPU cao là 18 giây, trong đó thời gian thực tế của đồng hồ treo tường mất 2 giây .

Để có được thời gian thực tế bạn làm,

#include <chrono>

auto t_start = std::chrono::high_resolution_clock::now();
// the work...
auto t_end = std::chrono::high_resolution_clock::now();

double elapsed_time_ms = std::chrono::duration<double, std::milli>(t_end-t_start).count();

2
Tôi sẽ không thể sử dụng std :: chrono nếu không có câu trả lời này, cảm ơn!
giles

13

boost 1.46.0 trở lên bao gồm thư viện Chrono :

lớp thread_clock cung cấp quyền truy cập vào đồng hồ treo tường của luồng thực, tức là đồng hồ thời gian CPU thực của luồng đang gọi. Thời gian hiện tại tương đối của luồng có thể được lấy bằng cách gọi thread_clock :: now ()

#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 ++ 11std::chronokhông gian tên với nội dung gần như giống nhau.
ulidtko

12

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;

}

8

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

  1. Đồng hồ thời gian thực trên toàn hệ thống
  2. Hệ thống đồng hồ đơn âm rộng
  3. Mỗi quy trình thời gian CPU
  4. Mỗi quá trình Thời gian CPU luồng

Mã 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";
}

`


6

chỉ trong trường hợp bạn đang sử dụng Unix, bạn có thể sử dụng timeđể lấy thời gian thực thi:

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

5

Chỉ một lưu ý nhỏ: nếu bạn đang chạy trên Windows và 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 (có thể là) nano giây.


5

Đối với tôi, cách dễ dàng 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();

bằng cách sử dụng đoạn mã này, bạn không cần phải làm theo cách cổ điển end - start.

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


t.elapsed () tính bằng giây hay mili-giây?
mkuse

4

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

Để 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ó 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 việc chuẩn hóa câu trả lời của Windows để nó cũng trả về số mili giây kể từ năm 1970, thì bạn sẽ phải điều chỉnh câu trả lời của mình thêm 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.


4

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

tstart = clock();

// ...do something...

tend = clock();

Sau đó, bạn sẽ cần những thứ sau để có thời gian tính bằng giây:

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

0

Điều này có vẻ hoạt động tốt đối với 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;
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.