【问题标题】:Proper method of using std::chrono使用 std::chrono 的正确方法
【发布时间】:2016-04-20 17:32:59
【问题描述】:

虽然我意识到这可能是许多相同的问题之一,但我似乎无法弄清楚如何正确使用 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;
}

由于某种原因,这只会返回整数值作为差值,该差值以每秒 1 的速率递增,但从任意值开始,通常为负值。

我做错了什么?有更好的方法吗?

【问题讨论】:

  • 两个整数参数相除的结果是一个整数值。
  • @SergeyA 这修复了结果不是浮点数,但它仍然从错误的数字开始。
  • return std::chrono::duration_cast&lt;ms&gt;(now.time_since_epoch()).count() / 1000.0F;
  • @Arkathorn 如果您计算std::chrono::time_points 上的差异,您应该会获得更好的精度。
  • 您应该使用浮点表示返回自定义的秒持续时间,而不是除以 1000

标签: c++ time chrono


【解决方案1】:
  • 除非万不得已,否则不要逃避 chrono 类型系统。这意味着不要使用 .count(),除非是 I/O 或与旧版 API 交互。

这意味着:不要使用float 作为时间点。

  • 不要打扰high_resolution_clock。这始终是system_clocksteady_clock 的typedef。如需更便携的代码,请选择后者。

.

#include <iostream>
#include <chrono>

using Time = std::chrono::steady_clock;
using ms = std::chrono::milliseconds;

首先,您需要一个表示为float 和单位为seconds 的持续时间。你就是这样做的:

using float_sec = std::chrono::duration<float>;

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

using float_time_point = std::chrono::time_point<Time, float_sec>;

现在您的getCurrentTime() 可以返回Time::now()。不要大惊小怪:

float_time_point
getCurrentTime() {
    return Time::now();
}

您的 main,因为它必须执行 I/O,因此负责将 chrono 类型解包为标量,以便它可以打印它们:

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

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

【讨论】:

  • 使用此代码getCurrentTime().time_since_epoch().count() 将始终返回相同的值。知道为什么吗?
  • @Arkathorn:在我的系统上,它返回自计算机启动以来的浮点秒数。每次我运行程序时,它都会按预期变化。如果我连续调用它两次,它似乎具有相同的值,因为它的打印精度仅为每秒十分之一。你在哪个平台上?
  • Windows 10。它总是返回1.46119e+012
  • (其实是1.4612e+009)
  • @Arkathorn: float 没有您想要的精度(跟踪数十亿秒中的分数)。您要么需要切换到 steady_clock 以获得自纪元以来的秒数,要么切换到 double 以获得额外的精度。
【解决方案2】:

这个程序做了类似的事情。希望它展示了 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;
}

示例输出:

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

【讨论】:

    猜你喜欢
    • 2019-10-10
    • 1970-01-01
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    相关资源
    最近更新 更多