Cap*_*man 3 c++ performance time
我说的是老式的 time() 函数,它返回自纪元以来的秒数(UTC)。这应该是单调的,对吧?
在我的测试中(见下文),它的运行速度比使用 CLOCK_MONOTONIC 的 Clock_gettime 快大约 10 倍,所以我想知道它是否可以用作单调计时器,用于我需要低延迟低分辨率单调计时器的情况。(例如,删除服务器上存在时间超过 15 秒的连接)
如果您好奇的话,这是代码:
#include <cstdio>
#include <chrono>
#include <time.h>
#include <sys/time.h>
#include <x86intrin.h>
using namespace std;
class Timer {
std::chrono::time_point<std::chrono::steady_clock> start;
public:
inline double t() {
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end - start;
return diff.count();
}
inline double milli() { return t() * 1000.0;}
Timer() :start(std::chrono::steady_clock::now()) {}
};
const int nloop = 10000000;
void cpp_steady() {
for (int i=0;i<nloop;i++) {
chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
}
}
void get_tod() {
timeval tv;
for (int i=0;i<nloop;i++) {
gettimeofday(&tv, 0);
}
}
void get_clock() {
for (int i=0;i<nloop;i++) {
clock_t t = clock();
}
}
void get_time() {
int x =0;
for (int i=0;i<nloop;i++) {
time_t t = time(0);
x+=t*3;
}
fprintf(stderr,"%d\n",x);
}
void get_clock_gettime() {
timespec ts;
for (int i=0;i<nloop;i++) {
clock_gettime(CLOCK_MONOTONIC, &ts);
}
}
void get_rdtsc() {
for (int i=0;i<nloop;i++) {
__rdtsc();
}
}
void emptyloop() {
int x=0;
for (int i=0;i<nloop;i++) {
x+=3*i;
}
fprintf(stderr,"%d\n",x);
}
void measure(const char *name, void (*f)()) {
Timer t;
f();
double dur = t.milli();
printf(" %-15s : %.3f ms\n", name, dur);
}
int main () {
measure("cpp_steady", cpp_steady);
measure("gettimeofday", get_tod);
//measure("clock", get_clock); //too fking slow
measure("time", get_time);
measure("clock_gettime", get_clock_gettime);
measure("rdtsc", get_rdtsc);
measure("empty", emptyloop);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
./clk_bench 2>/dev/null
cpp_steady : 212.415 ms
gettimeofday : 200.733 ms
time : 19.526 ms
clock_gettime : 197.791 ms
rdtsc : 75.169 ms
empty : 2.821 ms
Run Code Online (Sandbox Code Playgroud)
(顺便说一句,我知道这只是几纳秒的问题,并不重要,但实际上 time_t 也消耗更少的内存,并且比其他替代方案更便携......)
time除了不保证单调之外,没有明确的答案。
它只是返回内核认为的当前时间。如果存在保证时钟永远不会倒退的操作程序,并且遵守这些程序,那么它应该是单调的。例如,在用于ntpd时间同步的 Unix 机器上,时钟永远不应该向后运行。但是,如果管理员(在机器上具有管理员权限的人)发现机器时间不准确并将其向后修正,那么任何单调假设都将是错误的。