#问题:请优化下面函数,要求多线程安全,耗时减小
static inline void GetSysTime(s8* pTimeBuf, u32 dwSize, BOOL32 bFileName = FALSE) {if (pTimeBuf == NULL) {return;}
#if defined(_MSC_VER)SYSTEMTIME sys = {0}; GetLocalTime( &sys ); sprintf_s(pTimeBuf, dwSize, "%04d-%02d-%02d_%02d:%02d:%02d.%03d", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);
#elsetime_t timer;struct tm* ptTm = NULL;time(&timer);ptTm = localtime(&timer);if (!ptTm) {return;}if (bFileName) {// 日志文件名称snprintf(pTimeBuf, dwSize, "%04d-%02d-%02d_%02d-%02d-%02d", ptTm->tm_year + 1900, ptTm->tm_mon + 1, ptTm->tm_mday, ptTm->tm_hour, ptTm->tm_min, ptTm->tm_sec);} else {// 打印时间struct timespec tTimeTick = {0};clock_gettime(CLOCK_MONOTONIC, &tTimeTick);snprintf(pTimeBuf, dwSize, "%04d-%02d-%02d %02d:%02d:%02d.%03d", ptTm->tm_year + 1900, ptTm->tm_mon + 1, ptTm->tm_mday, ptTm->tm_hour, ptTm->tm_min, ptTm->tm_sec, static_cast<s32>(tTimeTick.tv_nsec/1000));}
#endifpTimeBuf[dwSize - 1] = '\0';
}
C++11 实现线程安全的高效时间获取函数
下面是一个使用 C++11 标准实现的多线程安全、高效的 GetSysTime
函数版本:
#include <chrono>
#include <ctime>
#include <cstring>
#include <array>#if defined(_MSC_VER)
#include <Windows.h>
#else
#include <sys/time.h>
#endifstatic inline void GetSysTime(char* pTimeBuf, size_t bufSize, bool forFileName = false)
{if (pTimeBuf == nullptr || bufSize == 0) {return;}// 获取当前时间点const auto now = std::chrono::system_clock::now();const auto now_time_t = std::chrono::system_clock::to_time_t(now);// 线程安全地转换时间struct tm tm_info;
#if defined(_MSC_VER)localtime_s(&tm_info, &now_time_t);
#elselocaltime_r(&now_time_t, &tm_info);
#endif// 计算毫秒部分const auto since_epoch = now.time_since_epoch();const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch).count() % 1000;if (forFileName) {// 文件名格式: YYYY-MM-DD_HH-MM-SSsnprintf(pTimeBuf, bufSize, "%04d-%02d-%02d_%02d-%02d-%02d",tm_info.tm_year + 1900, tm_info.tm_mon + 1, tm_info.tm_mday,tm_info.tm_hour, tm_info.tm_min, tm_info.tm_sec);} else {// 普通时间格式: YYYY-MM-DD HH:MM:SS.mmmsnprintf(pTimeBuf, bufSize, "%04d-%02d-%02d %02d:%02d:%02d.%03d",tm_info.tm_year + 1900, tm_info.tm_mon + 1, tm_info.tm_mday,tm_info.tm_hour, tm_info.tm_min, tm_info.tm_sec,static_cast<int>(ms));}// 确保字符串以null结尾if (bufSize > 0) {pTimeBuf[bufSize - 1] = '\0';}
}// 使用固定大小缓冲区的重载版本
static inline void GetSysTime(std::array<char, 32>& timeBuf, bool forFileName = false)
{GetSysTime(timeBuf.data(), timeBuf.size(), forFileName);
}
关键优化点
-
线程安全性:
- 使用
localtime_r
(Unix-like) 和localtime_s
(Windows) 替代不安全的localtime
- 所有时间操作都使用线程安全的 C++11 标准库函数
- 使用
-
性能优化:
- 使用
std::chrono
高效获取时间 - 减少系统调用次数(相比原代码减少了不必要的调用)
- 使用更高效的格式化方式
- 使用
-
C++11 特性应用:
- 使用
std::chrono
时间库 - 提供
std::array
重载版本,避免缓冲区溢出风险 - 使用更现代的 C++ 类型(
size_t
替代u32
,bool
替代BOOL32
)
- 使用
-
代码质量改进:
- 更严格的参数检查
- 更清晰的变量命名
- 移除冗余代码
- 更一致的跨平台实现
使用示例
#include <iostream>int main() {// 使用动态缓冲区char timeBuf1[64];GetSysTime(timeBuf1, sizeof(timeBuf1), false);std::cout << "Current time: " << timeBuf1 << std::endl;// 使用固定大小缓冲区std::array<char, 32> timeBuf2;GetSysTime(timeBuf2, true);std::cout << "File name time: " << timeBuf2.data() << std::endl;return 0;
}
性能对比
与原实现相比,这个版本有以下性能优势:
- 减少系统调用:原 Linux 实现需要调用
time()
和clock_gettime()
两次,新版本只需一次系统调用 - 更高效的时间计算:使用
std::chrono
直接获取毫秒部分,避免额外的计算 - 内存访问更优:使用固定大小缓冲区时,编译器可以进行更好的优化
这个实现完全使用 C++11 标准,同时保持了跨平台兼容性,是原函数的一个高效、安全的替代方案。