使用std :: chrono的正确方法

Ark*_*orn 1 c++ time c++-chrono

虽然我意识到这可能是许多相同问题中的一个,但我似乎无法弄清楚如何正确使用std :: chrono.这是我拼凑在一起的解决方案.

#include <stdlib.h>
#include <iostream>
#include <chrono>

typedef std::chrono::high_resolution_clock Time;
typedef std::chrono::milliseconds ms;

float startTime;

float getCurrentTime();

int main () {
    startTime = getCurrentTime();
    std::cout << "Start Time: " << startTime << "\n";

    while(true) {
        std::cout << getCurrentTime() - startTime << "\n";
    }

    return EXIT_SUCCESS;
}

float getCurrentTime() {
    auto now = Time::now();
    return std::chrono::duration_cast<ms>(now.time_since_epoch()).count() / 1000;
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,这只会返回整数值作为差值,它以每秒1的速率向上递增,但从任意的,通常是负的值开始.

我究竟做错了什么?有没有更好的方法呢?

How*_*ant 10

  • 在你绝对不得不逃避计时型系统之前.这意味着.count()除了I/O或与遗留API交互之外,不要使用它.

这转换为:不要float用作time_point.

  • 不要打扰high_resolution_clock.这始终是一个typedef要么system_clocksteady_clock.要获得更多可移植代码,请选择后者之一.

.

#include <iostream>
#include <chrono>

using Time = std::chrono::steady_clock;
using ms = std::chrono::milliseconds;
Run Code Online (Sandbox Code Playgroud)

首先,你需要一个表示float和单位的持续时间seconds.这是你如何做到的:

using float_sec = std::chrono::duration<float>;
Run Code Online (Sandbox Code Playgroud)

接下来,你需要一个time_point它使用Time的时钟,并float_sec为它的持续时间:

using float_time_point = std::chrono::time_point<Time, float_sec>;
Run Code Online (Sandbox Code Playgroud)

现在你getCurrentTime()可以回来了Time::now().没有大惊小怪,没有麻烦:

float_time_point
getCurrentTime() {
    return Time::now();
}
Run Code Online (Sandbox Code Playgroud)

你的main,因为它必须做I/O,负责将计时器类型解压缩到标量中,以便它可以打印它们:

int main () {
    auto startTime = getCurrentTime();
    std::cout << "Start Time: " << startTime.time_since_epoch().count() << "\n";

    while(true) {
        std::cout << (getCurrentTime() - startTime).count() << "\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Arkathorn:“float”没有您正在寻找的精度(跟踪数十亿秒之间的分数)。您需要切换到“steady_clock”以获得自纪元以来的较低秒数,或者切换到“double”以获得额外的精度。 (2认同)

Ric*_*ges 5

这个程序做了类似的事情。希望它展示了 std::chrono 的一些功能(和方法):

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

int main()
{
    using namespace std::literals;
    namespace chrono = std::chrono;
    using clock_type = chrono::high_resolution_clock;

    auto start = clock_type::now();

    for(;;) {
        auto first = clock_type::now();

        // note use of literal - this is c++14
        std::this_thread::sleep_for(500ms);

        // c++11 would be this:
        //        std::this_thread::sleep_for(chrono::milliseconds(500));

        auto last = clock_type::now();
        auto interval = last - first;
        auto total = last - start;

        // integer cast
        std::cout << "we just slept for " << chrono::duration_cast<chrono::milliseconds>(interval).count() << "ms\n";

        // another integer cast
        std::cout << "also known as " << chrono::duration_cast<chrono::nanoseconds>(interval).count() << "ns\n";

        // floating point cast
        using seconds_fp = chrono::duration<double, chrono::seconds::period>;
        std::cout << "which is " << chrono::duration_cast<seconds_fp>(interval).count() << " seconds\n";

        std::cout << "  total time wasted: " << chrono::duration_cast<chrono::milliseconds>(total).count() << "ms\n";
        std::cout << "         in seconds: " << chrono::duration_cast<seconds_fp>(total).count() << "s\n";


        std::cout << std::endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

示例输出:

we just slept for 503ms
also known as 503144616ns
which is 0.503145 seconds
  total time wasted: 503ms
         in seconds: 0.503145s

we just slept for 500ms
also known as 500799185ns
which is 0.500799 seconds
  total time wasted: 1004ms
         in seconds: 1.00405s

we just slept for 505ms
also known as 505114589ns
which is 0.505115 seconds
  total time wasted: 1509ms
         in seconds: 1.50923s

we just slept for 502ms
also known as 502478275ns
which is 0.502478 seconds
  total time wasted: 2011ms
         in seconds: 2.01183s

Run Code Online (Sandbox Code Playgroud)