Bagaimana cara mendapatkan durasi, sebagai int milli dan detik float dari <chrono>?

94

Saya mencoba menggunakan perpustakaan chrono untuk pengatur waktu dan durasi.

Saya ingin dapat memiliki Duration frameStart;(dari awal aplikasi) dan Duration frameDelta;(waktu antar frame)

Saya harus bisa mendapatkan frameDeltadurasi sebagai milidetik dan detik mengambang.

Bagaimana Anda melakukan ini dengan <chrono>pustaka c ++ 11 yang baru ? Saya telah mengerjakannya dan melakukan googling (informasinya jarang). Kode ini memiliki template yang berat dan membutuhkan cast dan hal-hal khusus, saya tidak tahu cara menggunakan library ini dengan benar.

EddieV223
sumber
Tetapkan durasi ke durasi dengan rasio detik (atau milidetik) dan kemudian panggil count...
K-ballo
delta otomatis = durasi_cast <seconds> (frameDelta) .count (); Seperti ini? Ia kembali lama bukan pelampung.
EddieV223
3
@ K-ballo, jika durasi memiliki resolusi yang lebih tinggi daripada jenis yang Anda tetapkan, maka tugas akan salah format, untuk menghindari kehilangan presisi. Anda perlu menggunakan durasi dengan representasi floating point, atau gunakanduration_cast
Jonathan Wakely
@JonathanWakely: Oh, maka saya telah salah menggunakannya! :(
K-ballo

Jawaban:

155

Apakah ini yang kamu cari?

#include <chrono>
#include <iostream>

int main()
{
    typedef std::chrono::high_resolution_clock Time;
    typedef std::chrono::milliseconds ms;
    typedef std::chrono::duration<float> fsec;
    auto t0 = Time::now();
    auto t1 = Time::now();
    fsec fs = t1 - t0;
    ms d = std::chrono::duration_cast<ms>(fs);
    std::cout << fs.count() << "s\n";
    std::cout << d.count() << "ms\n";
}

yang bagi saya mencetak:

6.5e-08s
0ms
Howard Hinnant
sumber
2
mengapa tidak menggunakan autopada fsdan d?
TemplateRex
27
@rhalbersma: Penggunaan dari autoakan baik-baik saja d, karena duration_cast<ms>adalah ms. Namun untuk fs autotidak akan sesuai karena hasil dari t1-t0memiliki tipe high_resolution_clock::durationyang belum tentu sama dengan tipe duration<float>. Misalnya di sistem saya duration<long long, nano>. Jadi ada konversi implisit dari berbasis integral nanosecondske berbasis float secondsterjadi di baris itu, hanya karena jenis tujuan ditentukan dengan fsec.
Howard Hinnant
2
Itu informasi yang berguna. Hanya ingin tahu: apakah auto fs = std::chrono::duration_cast<fsec>(t1 - t0);terlalu berlebihan?
TemplateRex
@rhalbersma: Itu akan berhasil dengan baik, dan melakukan hal yang persis sama. Adapun yang harus disukai sepenuhnya gaya sejauh yang saya ketahui.
Howard Hinnant
2
Sadarilah bahwa dalam beberapa skenario dunia nyata (misalnya kompiler ms dan pustaka) 'high_resolution_clock' akan melewatkan waktu dalam urutan mikrodetik dan kode ini akan mengeluarkan nol,
jheriko
20

Menebak apa yang Anda minta. Saya berasumsi dengan pewaktu bingkai milidetik Anda mencari sesuatu yang bertindak seperti berikut,

double mticks()
{
    struct timeval tv;
    gettimeofday(&tv, 0);
    return (double) tv.tv_usec / 1000 + tv.tv_sec * 1000;
}

tetapi menggunakan std::chronosebagai gantinya,

double mticks()
{
    typedef std::chrono::high_resolution_clock clock;
    typedef std::chrono::duration<float, std::milli> duration;

    static clock::time_point start = clock::now();
    duration elapsed = clock::now() - start;
    return elapsed.count();
}

Semoga ini membantu.

Billy The Kid
sumber
Selamat datang di Stack Overflow. Akan sangat bagus jika Anda dapat memberikan detail tambahan ke kode Anda. Ini akan membantu orang lain memahami apa yang Anda coba capai dan bagaimana solusi Anda bekerja. Terima kasih!
Luís Cruz
FYI - ini adalah contoh TERJELAS, paling berguna dari lusinan yang saya ulas. Terima kasih telah membuat fungsi chrono yang selalu membingungkan dapat dipahami.
SMGreenfield
15

Saya tidak tahu apa artinya "milidetik dan detik float", tapi ini bisa memberi Anda gambaran:

#include <chrono>
#include <thread>
#include <iostream>

int main()
{
  auto then = std::chrono::system_clock::now();
  std::this_thread::sleep_for(std::chrono::seconds(1));
  auto now = std::chrono::system_clock::now();
  auto dur = now - then;
  typedef std::chrono::duration<float> float_seconds;
  auto secs = std::chrono::duration_cast<float_seconds>(dur);
  std::cout << secs.count() << '\n';
}
Jonathan Wakely
sumber
Saya kira dia menginginkan yang sebenarnya countsebagai float?
K-ballo
1
Itulah yang akan dicetak di bagian akhir. Tapi saya tidak tahu apakah dia menginginkan milidetik sebagai integer, atau milidetik melewati detik, atau apa.
Jonathan Wakely
Saya ingin bisa mendapatkan dari chrono :: durasi durasi direpresentasikan sebagai int milidetik, atau detik float (sepersekian detik)
EddieV223
Jawaban Howard tepat seperti itu
Jonathan Wakely
8

Dalam gaya AAA menggunakan idiom penginisialisasi yang diketik secara eksplisit :

#include <chrono>
#include <iostream>

int main(){
  auto start = std::chrono::high_resolution_clock::now();
  // Code to time here...
  auto end = std::chrono::high_resolution_clock::now();

  auto dur = end - start;
  auto i_millis = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
  auto f_secs = std::chrono::duration_cast<std::chrono::duration<float>>(dur);
  std::cout << i_millis.count() << '\n';
  std::cout << f_secs.count() << '\n';
}
Chris Drew
sumber