欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 【C++11】获取日期时间,用于写日志

【C++11】获取日期时间,用于写日志

2025/4/17 23:46:53 来源:https://blog.csdn.net/lijian2017/article/details/147067942  浏览:    关键词:【C++11】获取日期时间,用于写日志

#问题:请优化下面函数,要求多线程安全,耗时减小

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);
}

关键优化点

  1. 线程安全性

    • 使用 localtime_r (Unix-like) 和 localtime_s (Windows) 替代不安全的 localtime
    • 所有时间操作都使用线程安全的 C++11 标准库函数
  2. 性能优化

    • 使用 std::chrono 高效获取时间
    • 减少系统调用次数(相比原代码减少了不必要的调用)
    • 使用更高效的格式化方式
  3. C++11 特性应用

    • 使用 std::chrono 时间库
    • 提供 std::array 重载版本,避免缓冲区溢出风险
    • 使用更现代的 C++ 类型(size_t 替代 u32bool 替代 BOOL32
  4. 代码质量改进

    • 更严格的参数检查
    • 更清晰的变量命名
    • 移除冗余代码
    • 更一致的跨平台实现

使用示例

#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;
}

性能对比

与原实现相比,这个版本有以下性能优势:

  1. 减少系统调用:原 Linux 实现需要调用 time()clock_gettime() 两次,新版本只需一次系统调用
  2. 更高效的时间计算:使用 std::chrono 直接获取毫秒部分,避免额外的计算
  3. 内存访问更优:使用固定大小缓冲区时,编译器可以进行更好的优化

这个实现完全使用 C++11 标准,同时保持了跨平台兼容性,是原函数的一个高效、安全的替代方案。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词