#问题:请优化下面函数,要求多线程安全,耗时减小
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);
#else
time_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));
}
#endif
pTimeBuf[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>
#endif
static 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);
#else
localtime_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-SS
snprintf(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.mmm
snprintf(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 标准,同时保持了跨平台兼容性,是原函数的一个高效、安全的替代方案。

6663

被折叠的 条评论
为什么被折叠?



