จะรับระยะเวลาเป็น int มิลลิวินาทีและลอยวินาทีจาก <chrono> ได้อย่างไร


94

ฉันพยายามใช้ chrono library สำหรับตัวจับเวลาและระยะเวลา

ฉันต้องการที่จะมีDuration frameStart;(ตั้งแต่เริ่มต้นแอป) และDuration frameDelta;(เวลาระหว่างเฟรม)

ฉันต้องสามารถรับframeDeltaระยะเวลาเป็นมิลลิวินาทีและวินาทีลอยได้

คุณทำสิ่งนี้กับ<chrono>ไลบรารีc ++ 11 ใหม่ได้อย่างไร ฉันทำงานกับมันและ googling (ข้อมูลกระจัดกระจาย) โค้ดได้รับการเทมเพลนอย่างมากและต้องใช้การร่ายและสิ่งต่างๆเป็นพิเศษฉันไม่สามารถหาวิธีใช้ไลบรารีนี้ได้อย่างถูกต้อง


กำหนดระยะเวลาให้เป็นช่วงเวลาด้วยอัตราส่วนวินาที (หรือมิลลิวินาที) แล้วเรียกcountมัน ...
K-ballo

เดลต้าอัตโนมัติ = ระยะเวลาการออกอากาศ <seconds> (frameDelta) .count (); แบบนี้? ผลตอบแทนที่ยาวนานไม่ใช่การลอย
EddieV223

3
@ K-ballo หากระยะเวลามีความละเอียดสูงกว่าประเภทที่คุณกำหนดงานนั้นจะผิดรูปแบบเพื่อหลีกเลี่ยงการสูญเสียความแม่นยำ คุณต้องใช้ระยะเวลากับการแสดงจุดลอยตัวหรือใช้duration_cast
Jonathan Wakely

@JonathanWakely: โอ้ฉันใช้มันผิด! :(
K-ballo

คำตอบ:


155

นี่คือสิ่งที่คุณกำลังมองหาใช่ไหม

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

ซึ่งสำหรับฉันพิมพ์ออกมา:

6.5e-08s
0ms

2
ทำไมไม่ใช้autoบนfsและd?
TemplateRex

27
@rhalbersma: การใช้autoน่าจะดีสำหรับการdเป็นผลจากการที่เป็นduration_cast<ms> msอย่างไรก็ตามสำหรับการfs autoจะไม่เหมาะสมเพราะผลมาจากการt1-t0มีประเภทซึ่งไม่จำเป็นต้องเป็นชนิดเดียวกับhigh_resolution_clock::duration ยกตัวอย่างเช่นในระบบของฉันมันเป็นduration<float> duration<long long, nano>ดังนั้นมีการแปลงจากนัยหนึ่งตามnanosecondsที่จะลอยตามที่เกิดขึ้นในบรรทัดที่เพียงเพราะประเภทปลายทางถูกระบุด้วยseconds fsec
Howard Hinnant

2
นั่นเป็นข้อมูลที่มีประโยชน์ แค่อยากรู้อยากเห็น: จะauto fs = std::chrono::duration_cast<fsec>(t1 - t0);โอ้อวดมากเกินไปหรือไม่?
TemplateRex

@rhalbersma: นั่นจะได้ผลเช่นกันและทำสิ่งเดียวกัน สิ่งที่ควรจะชอบเป็นโวหารเท่าที่ฉันกังวล
Howard Hinnant

2
โปรดทราบว่าในบางสถานการณ์ในโลกแห่งความเป็นจริง (เช่นคอมไพเลอร์ ms และไลบรารีเป็นต้น) 'high_resolution_clock' จะพลาดเวลาตามลำดับไมโครวินาทีและรหัสนี้จะคายศูนย์ออก
jheriko

21

เดาว่าคุณกำลังขออะไร ฉันสมมติว่าตัวจับเวลาเฟรมมิลลิวินาทีคุณกำลังมองหาสิ่งที่ทำหน้าที่ดังต่อไปนี้

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

แต่ใช้std::chronoแทน

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

หวังว่านี่จะช่วยได้


ยินดีต้อนรับสู่ Stack Overflow จะเป็นการดีมากหากคุณสามารถให้รายละเอียดเชิงอนุพันธ์กับโค้ดของคุณได้ ซึ่งจะช่วยให้ผู้อื่นเข้าใจว่าคุณกำลังพยายามทำอะไรอยู่และวิธีการแก้ปัญหาของคุณทำงานอย่างไร ขอบคุณ!
Luís Cruz

1
FYI - นี่คือตัวอย่างที่ชัดเจนและมีประโยชน์ที่สุดจากหลายสิบรายการที่ฉันตรวจสอบ ขอบคุณที่ทำให้ฟังก์ชั่นโครโนสับสนตลอดไปให้เข้าใจได้
SMGreenfield

15

ฉันไม่รู้ว่า "มิลลิวินาทีและวินาทีลอย" หมายถึงอะไร แต่สิ่งนี้ควรให้คุณได้ทราบ:

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

ฉันเดาว่าเขาต้องการตัวจริงcountเป็นfloat?
K-ballo

1
นั่นคือสิ่งที่จะพิมพ์ในตอนท้าย แต่ฉันไม่รู้ว่าเขาต้องการมิลลิวินาทีเป็นจำนวนเต็มหรือมิลลิวินาทีที่ผ่านมาหรืออะไร
Jonathan Wakely

ฉันต้องการที่จะได้รับจากโครโน :: ระยะเวลาระยะเวลาที่แสดงเป็นมิลลิวินาที int หรือวินาทีลอย (เศษเสี้ยววินาที)
EddieV223

คำตอบของ Howard ทำอย่างนั้น
Jonathan Wakely

8

ในรูปแบบ AAAโดยใช้สำนวน initializer ที่พิมพ์อย่างชัดเจน :

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