std::chrono::steady_clock în C++

Ceas monoton, care nu sare niciodată înapoi: ceasul corect pentru măsurarea duratelor.

Sintaxă
#include <chrono>
auto inceput = std::chrono::steady_clock::now();
// ...
auto durata = std::chrono::steady_clock::now() - inceput;

Ce face std::chrono::steady_clock

steady_clock avansează constant și nu este afectat de schimbarea orei din sistem. Valoarea lui nu are legătură cu data din calendar (de obicei pornește la boot), așa că se folosește doar pentru diferențe: iei now() la început și la sfârșit, scazi și obții o durată.

high_resolution_clock ar trebui să fie ceasul cu cea mai mare precizie, dar standardul îl lasă la latitudinea implementării: în libc++ (Apple clang) este un alias pentru steady_clock, în altele pentru system_clock. Recomandarea este să folosești direct steady_clock pentru măsurători.

Ce returnează

now() returnează un steady_clock::time_point; diferența a două puncte este o durată.

Exemple

Exemplul 1: Măsurarea unei operații

Timpul exact diferă la fiecare rulare și de la un calculator la altul.

#include <chrono>
#include <print>
#include <vector>

int main() {
    auto inceput = std::chrono::steady_clock::now();

    std::vector<long long> v;
    for (int i = 0; i < 1'000'000; ++i) v.push_back(i);

    auto durata = std::chrono::steady_clock::now() - inceput;
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(durata);
    std::println("{} elemente în {}", v.size(), ms);
}

Rezultat posibil (diferă la fiecare rulare)

1000000 elemente în 14ms

Exemplul 2: Proprietățile ceasurilor

Faptul că high_resolution_clock este același tip cu steady_clock este adevărat în libc++; cu alt compilator rezultatul poate fi altul.

#include <chrono>
#include <print>
#include <type_traits>

int main() {
    using namespace std::chrono;
    std::println("steady_clock::is_steady: {}", steady_clock::is_steady);
    std::println("system_clock::is_steady: {}", system_clock::is_steady);
    std::println("high_resolution_clock este steady_clock: {}",
                 std::is_same_v<high_resolution_clock, steady_clock>);
}

Rezultat

steady_clock::is_steady: true
system_clock::is_steady: false
high_resolution_clock este steady_clock: true

Greșeli frecvente

  • Afișezi steady_clock::now() ca dată. Valoarea nu are sens ca dată calendaristică; pentru ora reală folosește system_clock.
  • Măsori o operație foarte scurtă o singură dată, compilată fără optimizări. Rezultatul este dominat de zgomot; repetă operația de multe ori și compilează cu -O2.

Comenzi înrudite

  • std::chrono::system_clock: Ceasul sistemului: data și ora reale (UTC), care pot fi transformate în dată calendaristică.
  • std::chrono::duration_cast: Transformă o durată în altă unitate, trunchiind partea care nu încape (de exemplu secunde în minute).
  • std::chrono::duration: O durată de timp cu unitate de măsură: secunde, milisecunde, minute, ore. Conversiile sunt automate și sigure.