本文属于专栏《构建工业级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");
}