วิธีคำนวณความแตกต่างของเวลาใน C ++


96

วิธีที่ดีที่สุดในการคำนวณความแตกต่างของเวลาใน C ++ คืออะไร? ฉันกำหนดเวลาความเร็วในการดำเนินการของโปรแกรมดังนั้นฉันจึงสนใจเป็นมิลลิวินาที ยังดีกว่าวินาทีมิลลิวินาที ..

คำตอบที่ยอมรับใช้งานได้ แต่ต้องมี ctime หรือ time.h ตามที่ระบุไว้ในความคิดเห็น


หลอกลวง แต่ไม่สามารถเชื่อมโยงได้ในขณะนี้
Robert Gould

2
การปิดโหวตน้อยเกินไปสายเกินไป ฉันได้รับคำตอบที่ใช้งานได้ พยายามดี แต่ฉันไม่พบลิงค์เช่นกัน
Jack BeNimble

สำหรับ windows? จากนั้นลอง GetTickCount (Windows API)
aJ

5
โรเบิร์ต: โชคดีเพราะการโพสต์ใหม่ทำให้ได้รับคำตอบหลายคำตอบซึ่งหนึ่งในนั้นฉันเลือกไว้ อย่างจริงจังฉันตั้งคำถามถึงคุณค่าของการปิดโพสต์ที่มีการซ้อน จะเกิดอะไรขึ้นหากไม่ได้กล่าวถึงวิธีแก้ปัญหาในข้อแรก พัฒนาเทคโนโลยีใหม่ ๆ ? หาไม่เจอเพราะคนละหัว?
Jack BeNimble

2
@JackBeNimble ได้รับจุดจบของ "dups" สองสามตัวที่ไม่ได้ dups อย่างแน่นอน (อาจเป็นคนที่อ่านคำถามอย่างรวดเร็วและทำเครื่องหมายเพราะฟังดูคล้ายกับคำถามอื่น) ฉันเห็นด้วยอย่างยิ่งกับประเด็นของคุณ ... อาจเป็นจุดสำหรับการแลกเปลี่ยน meta stack: o
code_fodder

คำตอบ:


124

ดูstd::clock()ฟังก์ชัน

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

หากคุณต้องการคำนวณเวลาดำเนินการด้วยตัวเอง (ไม่ใช่สำหรับผู้ใช้) จะเป็นการดีกว่าถ้าทำในเครื่องหมายนาฬิกา (ไม่ใช่วินาที)

แก้ไข:
ไฟล์ส่วนหัวที่รับผิดชอบ - <ctime>หรือ<time.h>


4
โปรดทราบว่าแม้ว่า clock () จะส่งกลับเป็นจำนวนมิลลิวินาที แต่ความแม่นยำของ clock () อาจแย่กว่านั้นมาก อินสแตนซ์ Fir ใน Windows ความแม่นยำของฟังก์ชัน clock () เท่ากับ 40 ms
John Dibling

2
ฉันลองใช้กับ Mac 10.7 แอปของฉันรันไฟล์ 100 mb ใน 15 วินาที แต่เวลาที่แตกต่างคือรายงาน 61 วินาที ใช้ไม่มาก. ฉันคิดว่าเวลา () น่าจะดีกว่า
Miek

6
clock()ส่งคืนเวลา CPU ที่ใช้โดยโปรแกรม ดังนั้นหากโปรแกรมทำงานแบบขนานเวลาที่ฟังก์ชันส่งกลับมาจะเป็นการสะสมของเวลาที่ใช้กับ CPU ทั้งหมดแทนที่จะเป็นเวลาที่ผ่านไป cplusplus.com/reference/ctime/clock
Ameer Jewdaki

3
คำตอบนี้ทำให้เข้าใจผิดเนื่องจากแสดงเวลาของ CPU ไม่ใช่เวลานาฬิกาแขวนจริง
Ultraviolet

1
ฉันต้องเห็นด้วยกับ Ultraviolet ที่นี่การใช้เวลา CPU ในการวัดความเร็วของโปรแกรมดูเหมือนจะเป็นสิ่งที่ไม่ถูกต้อง OP ควรยกเลิกการทำเครื่องหมายว่าเป็นคำตอบที่ถูกต้อง IMO คุณควรใช้ std :: chrono :: steady_clock :: now () ตามที่อธิบายไว้โดยหลายคำตอบในเธรดต่อไปนี้stackoverflow.com/questions/2808398/easily-measure-elapsed-time
arunsun

37

หากคุณใช้ c ++ 11 นี่คือ Wrapper แบบธรรมดา (ดูส่วนสำคัญนี้):

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

หรือสำหรับ c ++ 03 บน * 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_;
};

ตัวอย่างการใช้งาน:

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
อีกทางเลือกหนึ่งคือการใช้ boost :: chrono แทน C ++ 11 STL std :: chrono namespace ขอบคุณสำหรับรหัสของคุณ
Didac Perez Parera

ระวัง: สิ่งนี้จะไม่ได้ผลหากผู้ใช้เปลี่ยนเวลาระหว่างTimer()และการโทรไปที่elapsed()if !std::chrono::high_resolution_clock::is_steady- ซึ่งเป็นกรณีบน Linux!
jhasse

30

ฉันจะพิจารณาการใช้ Boost อย่างจริงจังโดยเฉพาะ boost :: posix_time :: ptime และ boost :: posix_time :: time_duration (ที่http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time .html )

มันข้ามแพลตฟอร์มใช้งานง่ายและจากประสบการณ์ของฉันให้การแก้ปัญหาเวลาในระดับสูงสุดที่ระบบปฏิบัติการมอบให้ อาจมีความสำคัญมาก มันมีตัวดำเนินการ IO ที่ดีมาก

หากต้องการใช้เพื่อคำนวณความแตกต่างในการทำงานของโปรแกรม (เป็นไมโครวินาทีอาจจะมากเกินไป) จะมีลักษณะดังนี้ [เบราว์เซอร์เขียนไม่ได้ทดสอบ]:

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
แต่บูสต์ local_time () ไม่ใช่โมโนโทนิคดังนั้นจึงไม่ควรใช้ในการวัดไทม์แล็ป ฉันไม่พบวิธีเข้าถึง monotonic time จาก Boost
gatopeich

28

ฉันเพิ่มคำตอบนี้เพื่อชี้แจงว่าคำตอบที่ยอมรับนั้นแสดงเวลาของ CPU ซึ่งอาจไม่ใช่เวลาที่คุณต้องการ เพราะตามที่อ้างอิงมีเวลา CPU และเวลาของนาฬิกาผนัง เวลานาฬิกาแขวนคือเวลาที่แสดงเวลาที่ผ่านไปจริงโดยไม่คำนึงถึงเงื่อนไขอื่น ๆ เช่น CPU ที่ใช้ร่วมกันโดยกระบวนการอื่น ๆ ตัวอย่างเช่นฉันใช้โปรเซสเซอร์หลายตัวเพื่อทำงานบางอย่างและเวลาของ CPU สูงถึง18 วินาทีซึ่งใช้เวลา2 วินาทีในเวลานาฬิกาแขวนจริง

เพื่อให้ได้เวลาจริงที่คุณทำ

#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
ฉันจะไม่สามารถใช้ std :: chrono ได้หากไม่มีคำตอบนี้ขอบคุณ!
giles

13

บูสต์ 1.46.0 ขึ้นไปรวมถึงไลบรารีChrono :

คลาส thread_clock ให้การเข้าถึงนาฬิกาแขวนเธรดจริงนั่นคือนาฬิกาเวลา CPU จริงของเธรดการโทร เวลาปัจจุบันสัมพัทธ์ของเธรดสามารถรับได้โดยเรียกใช้ 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
นอกจากนี้C ++ 11ยังมีstd::chronoเนมสเปซที่มีเนื้อหาเกือบเหมือนกัน
ulidtko

12

ใน Windows: ใช้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

นอกจากนี้คุณยังสามารถใช้clock_gettime วิธีนี้สามารถใช้ในการวัด:

  1. นาฬิกาแบบเรียลไทม์ทั้งระบบ
  2. นาฬิกาโมโนโทนิกแบบกว้างของระบบ
  3. ต่อเวลาประมวลผล CPU
  4. ต่อกระบวนการเธรดเวลา CPU

รหัสมีดังนี้:

#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

ในกรณีที่คุณใช้ Unix คุณสามารถใช้timeเพื่อรับเวลาดำเนินการ:

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

5

เพียงแค่สังเกตด้าน: ถ้าคุณกำลังทำงานบน Windows และคุณจริงๆต้องแม่นยำจริงๆคุณสามารถใช้QueryPerformanceCounter จะให้เวลาคุณในนาโนวินาที(อาจ)


5

สำหรับฉันวิธีที่ง่ายที่สุดคือ:

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

end - startใช้ชิ้นส่วนของรหัสนี้คุณไม่ต้องทำคลาสสิก

เพลิดเพลินไปกับแนวทางที่คุณชื่นชอบ


t.elapsed () เป็นวินาทีหรือ mili-sec?
mkuse

4

รับเวลาของระบบเป็นมิลลิวินาทีที่จุดเริ่มต้นและอีกครั้งในตอนท้ายและลบออก

หากต้องการรับจำนวนมิลลิวินาทีตั้งแต่ปี 1970 ใน POSIX คุณต้องเขียน:

struct timeval tv;

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

หากต้องการรับจำนวนมิลลิวินาทีตั้งแต่ปี 1601 บน Windows คุณจะต้องเขียน:

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 ให้เป็นปกติเพื่อให้ตอบกลับเป็นจำนวนมิลลิวินาทีตั้งแต่ปี 1970 คุณจะต้องปรับคำตอบของคุณโดย 11644473600000 มิลลิวินาที แต่นั่นไม่จำเป็นถ้าสิ่งที่คุณสนใจคือเวลาที่ผ่านไป


4

หากคุณกำลังใช้:

tstart = clock();

// ...do something...

tend = clock();

จากนั้นคุณจะต้องมีสิ่งต่อไปนี้เพื่อรับเวลาเป็นวินาที:

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

0

ดูเหมือนว่าจะใช้งานได้ดีสำหรับ 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;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.