C ++ 'da bir zaman farkı nasıl hesaplanır


97

C ++ 'da bir saat farkını hesaplamanın en iyi yolu nedir? Bir programın yürütme hızını zamanlıyorum, bu yüzden milisaniyelerle ilgileniyorum. Daha da iyisi, saniye. Milisaniye ..

Kabul edilen cevap işe yarıyor, ancak yorumlarda belirtildiği gibi ctime veya time.h'yi içermesi gerekiyor.


Dupe, ancak şu anda bağlantı kuramıyor
Robert Gould

2
Kapatmak için oy çok az, çok geç. Çalışan bir cevabım var. Yine de iyi deneme. Btw, ben de bir bağlantı bulamadım.
Jack BeNimble

Pencereler için mi? daha sonra GetTickCount (Windows API)
aJ'yi

5
Robert: Neyse ki, yeni gönderi birkaç yanıta daha izin verdiği için, bunlardan birini seçtim. Cidden, bir çift gönderiyi kapatmanın değerini sorguluyorum. Ya ilkinde bazı çözümlerden bahsedilmediyse? Yeni teknolojiler mi geliştirildi? Farklı başlıklar yüzünden bulamıyor musunuz?
Jack BeNimble

2
@JackBeNimble, tam olarak dup olmayan birkaç "dup" nin alıcı tarafında yer aldı (belki soruyu hızlıca okuyup başka bir soruya benzediği için işaretleyen insanlar), fikrinize kesinlikle katılıyorum ... muhtemelen meta yığın değişimi için bir puan: o
code_fodder

Yanıtlar:


125

İşleve bakın std::clock().

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

Kendi için yürütme süresini hesaplamak istiyorsanız (kullanıcı için değil), bunu saat tiklerinde (saniye değil) yapmak daha iyidir.

DÜZENLEME:
sorumlu başlık dosyaları - <ctime>veya<time.h>


4
Clock () bir dizi milisaniye döndürse de, clock () kesinliğinin bundan çok daha kötü olabileceğini unutmayın. Windows'ta ilk örnek clock () işlevinin hassasiyeti 40 ms gibi bir şeydir.
John Dibling

2
Bunu Mac 10.7'de denedim. Uygulamam 100 mb'lik bir dosyayı 15 saniyede çalıştırıyor, ancak fark süresi 61 saniye bildiriyor. Fazla kullanım yok. Sanırım zaman () muhtemelen daha iyi.
Miek

6
clock()program tarafından tüketilen CPU süresini döndürür. Dolayısıyla, program paralel olarak çalıştırılırsa, işlevin döndürdüğü süre, geçen süre yerine tüm CPU'larda harcanan sürenin toplamı olacaktır cplusplus.com/reference/ctime/clock
Ameer Jewdaki

4
Bu cevap yanıltıcıdır çünkü gerçek duvar saati zamanını değil, CPU zamanını gösterir.
Ultraviolet

1
Burada Ultraviyole'ye katılıyorum, bir programın hızını ölçmek için CPU zamanını kullanmak yapılacak yanlış bir şey gibi görünüyor. OP, bunun doğru yanıt olarak işaretini kaldırmalıdır. IMO, std :: chrono :: steady_clock :: now () 'ı aşağıdaki iş parçacığında birden fazla yanıtla açıklandığı gibi kullanmalısınız stackoverflow.com/questions/2808398/easily-measure-elapsed-time
arunsun

37

c ++ 11 kullanıyorsanız, işte basit bir sarmalayıcı (bu özete bakın ):

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

Veya * nix üzerinde c ++ 03 için:

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

Kullanım örneği:

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
Diğer bir seçenek de C ++ 11 STL std :: chrono ad alanı yerine boost :: chrono kullanmaktır. Kodunuz için teşekkürler.
Didac Perez Parera

Dikkat: Kullanıcı zamanını Timer()ve elapsed()if çağrısı arasında değiştirirse bu işe yaramaz !std::chrono::high_resolution_clock::is_steady- Linux'ta durum böyle!
jhasse

30

Boost kullanımını, özellikle boost :: posix_time :: ptime ve boost :: posix_time :: time_duration ( http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time adresinde) ciddi şekilde düşünürdüm. .html ).

Çapraz platformdur, kullanımı kolaydır ve tecrübelerime göre bir işletim sisteminin sağladığı en yüksek zaman çözünürlüğünü sağlar. Muhtemelen aynı zamanda çok önemli; bazı çok güzel IO operatörleri sağlar.

Programın çalıştırılmasındaki farkı hesaplamak için kullanmak için (mikrosaniyelere; muhtemelen aşırıya kaçma), şöyle bir şeye benzeyecektir [tarayıcı yazılmış, test edilmemiş]:

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
Ancak boost local_time () tekdüze değildir , bu nedenle zaman atlamalarını ölçmek için kullanılmamalıdır. Boost'tan monoton zamana erişmenin bir yolunu bulamadım.
gatopeich

30

Bu cevabı, kabul edilen cevabın istediğiniz zaman olmayabilecek CPU zamanını gösterdiğini açıklığa kavuşturmak için ekledim . Uygun için referans vardır işlemci zamanı ve duvar saati . Duvar saati zamanı, diğer işlemler tarafından paylaşılan CPU gibi diğer koşullardan bağımsız olarak gerçek geçen zamanı gösteren zamandır. Örneğin, belirli bir görevi yerine getirmek için birden fazla işlemci kullandım ve CPU süresi yüksek 18 saniyeydi ve gerçek duvar saati süresinde 2 saniye sürdü .

Yaptığınız gerçek zamanı elde etmek için

#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
Bu cevap olmadan std :: chrono'yu kullanamazdım, teşekkürler!
giles

Bunun sistem saatinin değişmediğini varsaydığını unutmayın. Tüm koşulların üstesinden gelmek için kod yazıyorsanız, yaz saati, artık saniyeler, NTP ile zaman senkronizasyonu vb.
Dikkate almanız gerekir

13

boost 1.46.0 ve üstü Chrono kitaplığını içerir :

thread_clock sınıfı gerçek evre duvar saatine, yani çağıran evrenin gerçek CPU-zaman saatine erişim sağlar. Evre göreceli güncel zaman, thread_clock :: now () çağrısı ile elde edilebilir

#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
Ayrıca, C ++ 11std::chrono hemen hemen aynı içeriğe sahip ad alanına sahiptir.
ulidtko

12

Windows'ta: GetTickCount'u kullanın

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

    DWORD dw1 = GetTickCount();

    //Do something 

    DWORD dw2 = GetTickCount();

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

}

8

Clock_gettime özelliğini de kullanabilirsiniz . Bu yöntem şunları ölçmek için kullanılabilir:

  1. Sistem genelinde gerçek zamanlı saat
  2. Sistem geniş monotonik saat
  3. İşlem Başına CPU süresi
  4. İşlem İş Parçacığı başına CPU süresi

Kod aşağıdaki gibidir:

#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

Her ihtimale karşı Unix'te iseniz time, yürütme zamanını almak için kullanabilirsiniz :

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

5

Sadece bir yan not: Windows üzerinde çalışıyorsanız ve gerçekten hassasiyete ihtiyacınız varsa, QueryPerformanceCounter'ı kullanabilirsiniz . Size (potansiyel olarak) nano saniye cinsinden zaman verir .


5

Benim için en kolay yol:

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

bu kod parçasını kullanarak klasik yapmak zorunda değilsiniz end - start.

En sevdiğiniz yaklaşımın tadını çıkarın.


t.elapsed () saniyede mi milisaniyede mi?
mkuse

4

Başlangıçta ve sonunda milisaniye cinsinden sistem saatini alın ve çıkarın.

POSIX'te 1970'ten bu yana geçen milisaniye sayısını elde etmek için şunu yazarsınız:

struct timeval tv;

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

Windows'ta 1601'den beri geçen milisaniye sayısını almak için şunu yazarsınız:

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

Windows yanıtını, 1970'ten bu yana geçen milisaniye sayısını da döndürecek şekilde normalleştirmeye özen gösterdiyseniz, yanıtınızı 11644473600000 milisaniye olarak ayarlamanız gerekir. Ancak tüm ilgilendiğiniz geçen zaman ise bu gerekli değildir.


4

Eğer kullanıyorsanız:

tstart = clock();

// ...do something...

tend = clock();

O zaman saniyeler içinde zaman almak için aşağıdakilere ihtiyacınız olacak:

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

0

Bu, intel Mac 10.7 için iyi çalışıyor gibi görünüyor:

#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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.