Cara menghitung perbedaan waktu dalam C ++

97

Apa cara terbaik untuk menghitung perbedaan waktu dalam C ++? Saya menghitung waktu kecepatan eksekusi sebuah program, jadi saya tertarik dengan milidetik. Lebih baik lagi, detik.milliseconds ..

Jawaban yang diterima berfungsi, tetapi perlu menyertakan ctime atau time.h seperti yang disebutkan di komentar.

Jack BeNimble
sumber
Dupe, tetapi tidak dapat menautkan sekarang
Robert Gould
2
Pemungutan suara untuk ditutup terlalu sedikit, terlambat. Saya mendapat jawaban yang berhasil. Usaha yang bagus. Btw, saya juga tidak bisa menemukan tautan.
Jack BeNimble
Ini untuk windows? kemudian coba GetTickCount (Windows API)
aJ.
5
Robert: Untungnya, karena postingan baru memberikan beberapa jawaban lagi, salah satunya saya pilih. Serius, saya mempertanyakan nilai menutup posting dup. Bagaimana jika beberapa solusi tidak disebutkan di yang pertama? Teknologi baru dikembangkan? Tidak dapat menemukannya karena judul berbeda?
Jack BeNimble
2
@JackBeNimble telah menerima beberapa "dups" yang sebenarnya bukan dups (mungkin orang yang mungkin dengan cepat membaca pertanyaan dan menandainya karena terdengar mirip dengan pertanyaan lain), saya sangat setuju dengan maksud Anda ... mungkin poin untuk pertukaran meta stack: o
code_fodder

Jawaban:

124

Lihat std::clock()fungsinya.

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

Jika Anda ingin menghitung waktu eksekusi untuk diri sendiri (bukan untuk pengguna), sebaiknya lakukan ini dalam hitungan jam (bukan detik).

EDIT:
file header yang bertanggung jawab - <ctime>atau<time.h>

bayda
sumber
4
Perlu diingat bahwa meskipun clock () mengembalikan sejumlah milidetik, ketepatan clock () bisa jauh lebih buruk dari itu. Contoh fir di Windows ketepatan fungsi clock () adalah sekitar 40 ms.
John Dibling
2
Saya mencoba ini di Mac 10.7. aplikasi saya mengeksekusi file 100 mb dalam 15 detik, tetapi waktu diff melaporkan 61 detik. Tidak banyak gunanya. Saya pikir waktu () mungkin lebih baik.
Miek
6
clock()mengembalikan waktu CPU yang dikonsumsi oleh program. Jadi jika program dijalankan secara paralel, waktu yang dikembalikan oleh fungsi akan menjadi akumulasi waktu yang dihabiskan di semua CPU, bukan waktu yang telah berlalu cplusplus.com/reference/ctime/clock
Ameer Jewdaki
4
Jawaban ini menyesatkan karena ini menunjukkan waktu CPU, bukan waktu jam dinding sebenarnya.
Ultraviolet
1
Saya harus setuju dengan Ultraviolet di sini, menggunakan waktu CPU untuk mengukur kecepatan program sepertinya hal yang salah untuk dilakukan. OP harus menghapus tanda ini sebagai jawaban yang benar. IMO Anda harus menggunakan std :: chrono :: steady_clock :: now () seperti yang dijelaskan oleh beberapa jawaban di utas berikut stackoverflow.com/questions/2808398/easily-measure-elapsed-time
arunsun
37

jika Anda menggunakan c ++ 11, berikut adalah pembungkus sederhana (lihat intinya ):

#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_;
};

Atau untuk c ++ 03 di * 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_;
};

Contoh penggunaan:

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;
}
gongzhitaao
sumber
2
Pilihan lain adalah menggunakan boost :: chrono daripada namespace C ++ 11 STL std :: chrono. Terima kasih atas kode Anda.
Didac Perez Parera
Hati-hati: Ini tidak akan berfungsi jika pengguna mengubah waktu antara Timer()dan panggilan ke elapsed()if !std::chrono::high_resolution_clock::is_steady- yang terjadi di Linux!
jhasse
30

Saya akan secara serius mempertimbangkan penggunaan Boost, terutama boost :: posix_time :: ptime dan boost :: posix_time :: time_duration (di http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time .html ).

Ini lintas platform, mudah digunakan, dan menurut pengalaman saya memberikan tingkat resolusi waktu tertinggi yang disediakan oleh sistem operasi. Mungkin juga sangat penting; ini menyediakan beberapa operator IO yang sangat bagus.

Untuk menggunakannya untuk menghitung perbedaan dalam eksekusi program (menjadi mikrodetik; mungkin berlebihan), akan terlihat seperti ini [browser ditulis, tidak diuji]:

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';
CD Jeremy
sumber
3
Tetapi boost local_time () tidak monotonik sehingga tidak boleh digunakan untuk mengukur selang waktu. Saya belum menemukan cara untuk mengakses waktu monotonik dari Boost.
gatopeich
28

Saya menambahkan jawaban ini untuk mengklarifikasi bahwa jawaban yang diterima menunjukkan waktu CPU yang mungkin bukan waktu yang Anda inginkan. Karena menurut referensi , ada waktu CPU dan waktu jam dinding . Waktu jam dinding adalah waktu yang menunjukkan waktu berlalu yang sebenarnya terlepas dari kondisi lain seperti CPU yang digunakan bersama oleh proses lain. Misalnya, saya menggunakan beberapa prosesor untuk melakukan tugas tertentu dan waktu CPU tinggi 18 detik di mana sebenarnya dibutuhkan 2 detik dalam waktu jam dinding sebenarnya.

Untuk mendapatkan waktu aktual yang Anda lakukan,

#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();
Ultraungu
sumber
2
Saya tidak akan bisa menggunakan std :: chrono tanpa jawaban ini, terima kasih!
giles
13

meningkatkan 1.46.0 dan lebih tinggi termasuk perpustakaan Chrono :

kelas thread_clock menyediakan akses ke thread jam dinding yang sebenarnya, yaitu jam waktu CPU sebenarnya dari thread pemanggil. Waktu relatif saat ini utas dapat diperoleh dengan memanggil 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";
Gabi Davar
sumber
7
Selain itu, C ++ 11 memiliki std::chrononamespace dengan konten yang hampir sama.
ulidtko
12

Di Windows: gunakan GetTickCount

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

    DWORD dw1 = GetTickCount();

    //Do something 

    DWORD dw2 = GetTickCount();

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

}
aJ.
sumber
8

Anda juga dapat menggunakan clock_gettime . Metode ini dapat digunakan untuk mengukur:

  1. Jam waktu nyata di seluruh sistem
  2. Jam monotonik lebar sistem
  3. Per Proses waktu CPU
  4. Per proses waktu Thread CPU

Kode adalah sebagai berikut:

#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";
}

`

Richard
sumber
6

untuk berjaga-jaga jika Anda menggunakan Unix, Anda dapat menggunakan timeuntuk mendapatkan waktu eksekusi:

$ g++ myprog.cpp -o myprog
$ time ./myprog
fengshaun
sumber
5

Sekadar catatan: jika Anda menjalankan Windows, dan Anda benar-benar membutuhkan ketepatan, Anda dapat menggunakan QueryPerformanceCounter . Ini memberi Anda waktu dalam (berpotensi) nano detik.

v3.
sumber
5

Bagi saya cara yang paling mudah adalah:

#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();

menggunakan potongan kode ini, Anda tidak perlu melakukan yang klasik end - start.

Nikmati pendekatan favorit Anda.

pengguna1823890
sumber
apakah t.elapsed () dalam detik atau mili-sec?
mkuse
4

Dapatkan waktu sistem dalam milidetik di awal, dan lagi di akhir, dan kurangi.

Untuk mendapatkan jumlah milidetik sejak 1970 di POSIX Anda harus menulis:

struct timeval tv;

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

Untuk mendapatkan jumlah milidetik sejak 1601 di Windows, Anda harus menulis:

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

Jika Anda ingin menormalkan jawaban Windows agar juga mengembalikan jumlah milidetik sejak 1970, maka Anda harus menyesuaikan jawaban Anda dengan 11644473600000 milidetik. Tetapi itu tidak perlu jika yang Anda pedulikan hanyalah waktu yang telah berlalu.

Jared Oberhaus
sumber
4

Jika Anda menggunakan:

tstart = clock();

// ...do something...

tend = clock();

Maka Anda akan membutuhkan yang berikut untuk mendapatkan waktu dalam hitungan detik:

time = (tend - tstart) / (double) CLOCKS_PER_SEC;
Robert White
sumber
0

Ini tampaknya berfungsi dengan baik untuk 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;
Miek
sumber