C++ 在 Linux 上获取毫秒时间——clock() 似乎无法正常工作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/588307/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:06:36  来源:igfitidea点击:

C++ obtaining milliseconds time on Linux -- clock() doesn't seem to work properly

c++timerclock

提问by hasen

On Windows, clock()returns the time in milliseconds, but on this Linux box I'm working on, it rounds it to the nearest 1000 so the precision is only to the "second" level and not to the milliseconds level.

在 Windows 上,clock()以毫秒为单位返回时间,但在我正在使用的这个 Linux 机器上,它会将其四舍五入到最接近的 1000,因此精度仅到“秒”级别而不是毫秒级别。

I found a solution with Qt using the QTimeclass, instantiating an object and calling start()on it then calling elapsed()to get the number of milliseconds elapsed.

我找到了一个 Qt 使用QTime该类的解决方案,实例化一个对象并调用start()它,然后调用elapsed()以获取经过的毫秒数。

I got kind of lucky because I'm working with Qt to begin with, but I'd like a solution that doesn't rely on third party libraries,

我有点幸运,因为我开始使用 Qt,但我想要一个不依赖第三方库的解决方案,

Is there no standard way to do this?

有没有标准的方法来做到这一点?

UPDATE

更新

Please don't recommend Boost ..

请不要推荐Boost ..

If Boost and Qt can do it, surely it's not magic, there must be something standard that they're using!

如果 Boost 和 Qt 可以做到,那肯定不是魔术,他们使用的一定是标准的东西!

采纳答案by Adam Hawes

You could use gettimeofday at the start and end of your method and then difference the two return structs. You'll get a structure like the following:

您可以在方法的开头和结尾使用 gettimeofday,然后区分两个返回结构。您将获得如下结构:

struct timeval {
  time_t tv_sec;
  suseconds_t tv_usec;
}

EDIT: As the two comments below suggest, clock_gettime(CLOCK_MONOTONIC) is a much better choice if you have it available, which should be almost everywhere these days.

编辑:正如下面的两条评论所暗示的那样,clock_gettime(CLOCK_MONOTONIC) 是一个更好的选择,如果你有它,现在应该几乎无处不在。

EDIT: Someone else commented that you can also use modern C++ with std::chrono::high_resolution_clock, but that isn't guaranteed to be monotonic. Use steady_clock instead.

编辑:其他人评论说,您也可以将现代 C++ 与 std::chrono::high_resolution_clock 一起使用,但这并不能保证是单调的。使用 stable_clock 代替。

回答by CTT

#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    struct timeval start, end;

    long mtime, seconds, useconds;    

    gettimeofday(&start, NULL);
    usleep(2000);
    gettimeofday(&end, NULL);

    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;

    mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;

    printf("Elapsed time: %ld milliseconds\n", mtime);

    return 0;
}

回答by Johannes Schaub - litb

Please note that clockdoes notmeasure wall clock time. That means if your program takes 5 seconds, clockwill not measure 5 seconds necessarily, but could more (your program could run multiple threads and so could consume more CPU than real time) or less. It measures an approximation of CPU timeused. To see the difference consider this code

请注意,clock不能衡量挂钟的时间。这意味着如果您的程序需要 5 秒,clock则不一定需要 5 秒,但可能更多(您的程序可以运行多个线程,因此可能比实时消耗更多的 CPU)或更少。它测量使用的CPU 时间的近似值。要查看差异,请考虑此代码

#include <iostream>
#include <ctime>
#include <unistd.h>

int main() {
    std::clock_t a = std::clock();
    sleep(5); // sleep 5s
    std::clock_t b = std::clock();

    std::cout << "difference: " << (b - a) << std::endl;
    return 0;
}

It outputs on my system

它在我的系统上输出

$ difference: 0

Because all we did was sleeping and not using any CPU time! However, using gettimeofdaywe get what we want (?)

因为我们所做的只是睡觉而不使用任何 CPU 时间!然而,使用gettimeofday我们得到我们想要的(?)

#include <iostream>
#include <ctime>
#include <unistd.h>
#include <sys/time.h>

int main() {
    timeval a;
    timeval b;

    gettimeofday(&a, 0);
    sleep(5); // sleep 5s
    gettimeofday(&b, 0);

    std::cout << "difference: " << (b.tv_sec - a.tv_sec) << std::endl;
    return 0;
}

Outputs on my system

我的系统上的输出

$ difference: 5

If you need more precision but want to get CPU time, then you can consider using the getrusagefunction.

如果您需要更高的精度但想要获得CPU 时间,那么您可以考虑使用该getrusage功能。

回答by Anonymous

I also recommend the tools offered by Boost. Either the mentioned Boost Timer, or hack something out of Boost.DateTime or there is new proposed library in the sandbox - Boost.Chrono: This last one will be a replacement for the Timer and will feature:

我还推荐 Boost 提供的工具。提到的 Boost Timer,或者从 Boost.DateTime 中破解一些东西,或者在沙箱中有新的提议库 - Boost.Chrono:最后一个将替代 Timer,并将具有以下特点:

  • The C++0x Standard Library's time utilities, including:
    • Class template duration
    • Class template time_point
    • Clocks:
      • system_clock
      • monotonic_clock
      • high_resolution_clock
  • Class template timer, with typedefs:
    • system_timer
    • monotonic_timer
    • high_resolution_timer
  • Process clocks and timers:
    • process_clock, capturing real, user-CPU, and system-CPU times.
    • process_timer, capturing elapsed real, user-CPU, and system-CPU times.
    • run_timer, convenient reporting of |process_timer| results.
  • The C++0x Standard Library's compile-time rational arithmetic.
  • C++0x 标准库的时间实用程序,包括:
    • 班级模板 duration
    • 班级模板 time_point
    • 时钟:
      • system_clock
      • monotonic_clock
      • high_resolution_clock
  • 类模板timer,带有 typedef:
    • system_timer
    • monotonic_timer
    • high_resolution_timer
  • 进程时钟和定时器:
    • process_clock,捕获真实时间、用户 CPU 时间和系统 CPU 时间。
    • process_timer,捕获实际、用户 CPU 和系统 CPU 时间。
    • run_timer,方便上报|process_timer| 结果。
  • C++0x 标准库的编译时有理算术。

Here is the sourceof the feature list

这是功能列表的来源

回答by Chris Redford

I've written a Timerclass based on CTT's answer. It can be used in the following way:

我已经Timer根据CTT 的回答编写了一个课程。它可以通过以下方式使用:

Timer timer = Timer();
timer.start();
/* perform task */
double duration = timer.stop();
timer.printTime(duration);

Here is its implementation:

这是它的实现:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
using namespace std;

class Timer {
private:

    timeval startTime;

public:

    void start(){
        gettimeofday(&startTime, NULL);
    }

    double stop(){
        timeval endTime;
        long seconds, useconds;
        double duration;

        gettimeofday(&endTime, NULL);

        seconds  = endTime.tv_sec  - startTime.tv_sec;
        useconds = endTime.tv_usec - startTime.tv_usec;

        duration = seconds + useconds/1000000.0;

        return duration;
    }

    static void printTime(double duration){
        printf("%5.6f seconds\n", duration);
    }
};

回答by Zachary Hamm

If you don't need the code to be portable to old unices, you can use clock_gettime(), which will give you the time in nanoseconds(if your processor supports that resolution). It's POSIX, but from 2001.

如果您不需要将代码移植到旧的 unices,您可以使用 clock_gettime(),它将为您提供以纳秒为单位的时间(如果您的处理器支持该分辨率)。这是 POSIX,但从 2001 年开始。

回答by JesperE

clock() has a often a pretty lousy resolution. If you want to measure time at the millisecond level, one alternative is to use clock_gettime(), as explained in this question.

clock() 的分辨率通常非常糟糕。如果您想在毫秒级别测量时间,另一种方法是使用 clock_gettime(),如本问题中所述。

(Remember that you need to link with -lrt on Linux).

(请记住,您需要在 Linux 上使用 -lrt 链接)。

回答by Martin G

With C++11 and std::chrono::high_resolution_clockyou can do this:

使用 C++11,std::chrono::high_resolution_clock你可以这样做:

#include <iostream>
#include <chrono>
#include <thread>
typedef std::chrono::high_resolution_clock Clock;

int main()
{
    std::chrono::milliseconds three_milliseconds{3};

    auto t1 = Clock::now();
    std::this_thread::sleep_for(three_milliseconds);
    auto t2 = Clock::now();

    std::cout << "Delta t2-t1: " 
              << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count()
              << " milliseconds" << std::endl;
}

Output:

输出:

Delta t2-t1: 3 milliseconds

Link to demo: http://cpp.sh/2zdtu

演示链接:http: //cpp.sh/2zdtu

回答by SoapBox

clock() doesn't return milliseconds or seconds on linux. Usually clock() returns microseconds on a linux system. The proper way to interpret the value returned by clock() is to divide it by CLOCKS_PER_SEC to figure out how much time has passed.

clock() 在 linux 上不返回毫秒或秒。通常clock() 在Linux 系统上返回微秒。解释 clock() 返回值的正确方法是将其除以 CLOCKS_PER_SEC 以计算已经过去了多少时间。

回答by Jon Trauntvein

In the POSIX standard clockhas its return value defined in terms of the CLOCKS_PER_SEC symbol and an implementation is free to define this in any convenient fashion. Under Linux, I have had good luck with the times()function.

在 POSIX 标准clock中,它的返回值是根据 CLOCKS_PER_SEC 符号定义的,并且实现可以以任何方便的方式自由地定义它。在 Linux 下,我很幸运地使用了该times()功能。