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

วิธีวัด Execution Time ของโค้ดใน C++ (High Resolution Clock)

ภาพรวม

ใน C++11+ สามารถวัดเวลาทำงานของโค้ดได้แม่นยำด้วย std::chrono::high_resolution_clock ซึ่งให้ความละเอียดสูงสุดที่ระบบรองรับ (มักเป็น Nanoseconds)

Syntax พื้นฐาน


#include <chrono>
using namespace std::chrono;

auto start = high_resolution_clock::now();
// Code to measure
auto stop = high_resolution_clock::now();

auto duration = duration_cast(stop - start);
cout << "Time: " << duration.count() << " microseconds";

ตัวอย่างโค้ดครบถ้วน


#include <iostream>
#include <chrono>
#include <vector>
#include <algorithm>
#include <random>
using namespace std;
using namespace std::chrono;

void measureSort(const string& name, vector& data) {
    auto start = high_resolution_clock::now();
    sort(data.begin(), data.end());
    auto stop = high_resolution_clock::now();
    
    auto duration = duration_cast(stop - start);
    cout << name << ": " << duration.count() << " µs\n";
}

int main() {
    const int SIZE = 100000;
    vector data(SIZE);
    
    // Generate Random Data
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(1, 1000000);
    generate(data.begin(), data.end(), [&](){ return dis(gen); });
    
    // Test Multiple Runs
    for (int run = 1; run <= 3; run++) {
        vector copy = data;
        cout << "Run " << run << ": ";
        measureSort("std::sort", copy);
    }
    
    // Measure Specific Function
    auto start = high_resolution_clock::now();
    int sum = 0;
    for (int i = 0; i < 1000000; ++i) sum += i;
    auto stop = high_resolution_clock::now();
    
    auto ns = duration_cast(stop - start);
    auto us = duration_cast(stop - start);
    auto ms = duration_cast(stop - start);
    
    cout << "\nLoop Sum: " << ns.count() << " ns (" 
         << us.count() << " µs, " << ms.count() << " ms)\n";
    
    return 0;
}

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


Run 1: std::sort: 12450 µs
Run 2: std::sort: 11980 µs
Run 3: std::sort: 12120 µs

Loop Sum: 2450000 ns (2450 µs, 2 ms)

Duration Units และ Cast

UnitTypeCast FunctionTypical Use
Nanosecondsnanosecondsduration_cast<nanoseconds>High Precision, Short Operations
Microsecondsmicrosecondsduration_cast<microseconds>General Purpose (Recommended)
Millisecondsmillisecondsduration_cast<milliseconds>Longer Operations, Human Readable
Secondssecondsduration_cast<seconds>Very Long Operations
Customduration<double, ratio<1,1000000>>CustomFloating Point Precision

Best Practices สำหรับ Benchmarking

  1. Warm-up Runs: รัน 1-2 รอบก่อนวัดจริง (JIT, Cache, Branch Prediction)
  2. Multiple Iterations: วัดหลายรอบ หารด้วยจำนวนรอบ (Reduce Noise)
  3. Disable Optimizations สำหรับ Debug: -O0 แต่ Production Benchmark ควร -O2/-O3
  4. Prevent Dead Code Elimination: ใช้ Result (Print/Return) ไม่งั้น Compiler Optimize ทิ้ง
  5. Use volatile หรือ benchmark::DoNotOptimize (Google Benchmark)
  6. Pin CPU Core: taskset -c 0 ./benchmark (Linux)

Google Benchmark Library (Production Grade)


// Install: sudo apt-get install libbenchmark-dev
#include <benchmark/benchmark.h>

static void BM_Sort(benchmark::State& state) {
    vector data(state.range(0));
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(1, 1000000);
    
    for (auto _ : state) {
        generate(data.begin(), data.end(), [&](){ return dis(gen); });
        sort(data.begin(), data.end());
        benchmark::DoNotOptimize(data.data());
    }
}
BENCHMARK(BM_Sort)->Arg(100000);

BENCHMARK_MAIN();

Clocks Comparison

ClockMonotonicPrecisionUse Case
high_resolution_clockUsuallyHighestBenchmarking, Profiling
steady_clock✅ GuaranteedHighTimeouts, Intervals (Safe)
system_clock❌ No (Wall Time)VariableWall Clock Time, Time Points

หมายเหตุ: high_resolution_clock อาจเป็น Alias ของ steady_clock หรือ system_clock ขึ้นกับ Implementation