I'm talking about the old-school time() function that returns the number of seconds since the epoch, in UTC. This should be monotonic, right?
In my tests (see below) it runs about 10x faster than clock_gettime with CLOCK_MONOTONIC, so I was wondering if it can be used as a monotonic timer for situations where I need a low latency low resolution monotonic timer. (e.g. to drop connections that have been around for longer than 15 seconds on a server)
Here is the code in case you're curious:
#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;
}
And here is the output:
./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
(By the way, I know it's only a matter of a few nanoseconds and doesn't really matter, but actually time_t also consumes less memory and is more portable than the alternatives...)