本文属于专栏《构建工业级QPS百万级服务》系列简介-CSDN博客


1、结论

         c++11中获取unix时间最快的方式是clock_gettime和gettimeofday函数。

2、结论补充说明:

  • 在linux内核版本2.6之前,VDSO内核机制还没有引入时,gettimeofday需要在内核态与用户态之间切换,所以一些老的资料中,会让用户建立一个自己的时间缓存,但现在不需要了。
  • 单线程和多线程对时间获取的性能无影响,单线程可获取3000万次/秒,两个线程就可获取6000万次/秒。因为时间数据已经做到读写分离。当然,由于环境差异,会导致时间有差别,快速测试可使用文章后面的代码。

3、环境说明和测试代码:

        代码运行在32核linux机器,g++版本4.85,系统版本centos7。在我的测试环境中,单核clock_gettime、gettimeofday为3000万次/秒,chrono为1000万次/秒。(chrono慢的原因在《使用google profiler 对c++应用进行性能热点分析》中示例中可以了解到)

        编译命令 g++ test.cpp -std=c++11 -pthread

#include <iostream>
#include <chrono>
#include <ctime>
#include <sys/time.h>
#include <thread>
#include <vector>
#include <functional>

using namespace std;
using namespace std::chrono;

const int TEST_TIMES = 1000 * 1000 * 10;

long long getCurrentTimeByClockGetTime() {
    struct timespec spec;
    clock_gettime(CLOCK_REALTIME, &spec);
    return spec.tv_sec * 1000LL + spec.tv_nsec / 1000000;
}

long long getCurrentTimeByGetTimeOfDay() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000LL + tv.tv_usec / 1000;
}

long long getCurrentTimeByChrono() {
    return duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
}

void testFunction(const std::function<void()>& testFunc, const std::string& testName) {
    long long start = getCurrentTimeByChrono();
    for (int i = 0; i < TEST_TIMES; ++i) {
        testFunc();
    }
    long long end = getCurrentTimeByChrono();
    cout << "Using " << testName << " in thread " << this_thread::get_id() << ": " << end - start << " ms\n";
}

void testMultiThread(int thread_num, const std::function<void()>& testFunc, const std::string& testName) {
    vector<thread> threads;
    for (int i = 0; i < thread_num; ++i) {
        threads.emplace_back(testFunction, testFunc, testName);
    }
    for (auto& t : threads) {
        t.join();
    }
}

int main() {
    testMultiThread(1, getCurrentTimeByChrono, "chrono::high_resolution_clock");
    testMultiThread(10, getCurrentTimeByChrono, "chrono::high_resolution_clock");
    testMultiThread(1, getCurrentTimeByGetTimeOfDay, "gettimeofday");
    testMultiThread(10, getCurrentTimeByGetTimeOfDay, "gettimeofday");
    testMultiThread(1, getCurrentTimeByClockGetTime, "clock_gettime");
    testMultiThread(10, getCurrentTimeByClockGetTime, "clock_gettime");
}

更多推荐