Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

วัดเวลาการ Execute ด้วยความแม่นยำสูงใน C/C++ (chrono)


Library <chrono> ใน C++11 提供 High-Resolution Clock ที่นับได้ระดับ Nanoseconds เหมาะสำหรับ Benchmarking และ Performance Measurement

หลักการทำงาน

  1. บันทึกเวลาเริ่มต้น: auto start = Clock::now();
  2. รันโค้ดที่ต้องการวัด
  3. บันทึกเวลาสิ้นสุด: auto end = Clock::now();
  4. คำนวณความต่าง: duration_cast<nanoseconds>(end - start).count()

ตัวอย่างโค้ด

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

int main() {
    // ใช้ High Resolution Clock
    auto start_time = high_resolution_clock::now();
    
    // โค้ดที่ต้องการวัด (Empty Loop จำลอง Workload)
    for(int i = 0; i < 200000000; i++) {
        ; // No-op
    }
    
    auto end_time = high_resolution_clock::now();
    
    // คำนวณความต่างใน Nanoseconds
    auto duration_ns = duration_cast<nanoseconds>(end_time - start_time).count();
    
    cout << "Time difference: " << duration_ns << " nanoseconds" << endl;
    
    // แปลงเป็นหน่วยอื่นๆ
    cout << "Microseconds: " << duration_cast<microseconds>(end_time - start_time).count() << " µs" << endl;
    cout << "Milliseconds: " << duration_cast<milliseconds>(end_time - start_time).count() << " ms" << endl;
    cout << "Seconds: " << duration_cast<seconds>(end_time - start_time).count() << " s" << endl;
    
    return 0;
}

ผลลัพธ์ตัวอย่าง

Time difference: 536395307 nanoseconds
Microseconds: 536395 µs
Milliseconds: 536 ms
Seconds: 0 s

Clock Types ใน <chrono>

Clockลักษณะเหมาะสำหรับ
system_clockWall-clock time, สามารถปรับได้Timestamp, Logging
steady_clockMonotonic, ไม่ปรับได้, SteadyBenchmarking (แนะนำ)
high_resolution_clockความละเอียดสูงสุด (อาจเป็น alias ของ steady_clock)Benchmarking

Best Practices

  • ใช้ steady_clock สำหรับวัดระยะเวลา (Monotonic)
  • รันหลายรอบแล้วหาค่าเฉลี่ย (Warm-up runs)
  • ปิด Optimization (-O0) ตอน Debug, เปิด (-O2/-O3) ตอน Benchmark จริง
  • หลีกเลี่ยง I/O ภายในส่วนที่วัด

ฟังก์ชัน Helper สำหรับ Benchmark

template<typename Func>
long long benchmark_ns(Func func, int iterations = 1) {
    auto start = steady_clock::now();
    for (int i = 0; i < iterations; ++i) func();
    auto end = steady_clock::now();
    return duration_cast<nanoseconds>(end - start).count() / iterations;
}

// การใช้งาน
auto avg_ns = benchmark_ns([](){ 
    // code to benchmark
}, 1000);