能否使用__DATE__与__TIME__宏替代自定义函数以避免内存分配?
日志系统时间戳优化问题
我开发了一款日志系统,支持获取日志消息、日志级别及消息生成时间,能将内容输出到控制台和文件。但自定义的getTime()函数会产生约3次内存分配,我想避免这种情况,请问能不能用__DATE__和__TIME__宏替代这个函数?
原getTime()函数
std::string LoggingSystem::getTime() const { std::stringstream stream; auto currentTime = std::chrono::system_clock::now(); auto stampTime = std::chrono::system_clock::to_time_t(currentTime); tm newTime; localtime_s(&newTime, &stampTime); stream << std::put_time(&newTime, " %Y/%m/%d %H:%M:%S"); return stream.str(); }
原Log()函数
void SyncLogging::Log(const LogLevel& level, const std::string& message) const { std::lock_guard<std::mutex> lock(m_consoleLoggingMutex); std::cout << LogLevelToColorfulString(level) << message << getTime() << "\033[0m \n"; if (m_saveFileStatus) { std::lock_guard<std::mutex> lock(m_queueMutex); std::string formattedMessage = LogLevelToNormalString(level) + message + getTime(); m_messageList.push(formattedMessage); writeDataInFile(); } }
拟修改后的Log()函数
void SyncLogging::Log(const LogLevel& level, const std::string& message) const { std::lock_guard<std::mutex> lock(m_consoleLoggingMutex); std::cout << LogLevelToColorfulString(level) << message << " | " << __DATE__ << " " << __TIME__ << "\033[0m \n"; if (m_saveFileStatus) { std::lock_guard<std::mutex> lock(m_queueMutex); std::string formattedMessage = LogLevelToNormalString(level) + message + " | " + __DATE__ + " " + __TIME__; m_messageList.push(formattedMessage); writeDataInFile(); } }
回答
绝对不能用__DATE__和__TIME__宏替代getTime()函数,核心原因是:
这两个宏是编译期固定值,只会记录你编译程序的日期和时间,所有日志都会显示同一个时间点——程序编译完成的那一刻,完全失去了日志记录运行时时间戳的意义。
如果要减少内存分配,正确的优化方向是:
- 用固定缓冲区替代字符串流:预分配字符数组,直接用
strftime格式化时间到缓冲区,避免std::stringstream和临时std::string的内存开销:// 修改getTime为输出到缓冲区 void LoggingSystem::getTime(char* time_buf, size_t buf_size) const { auto currentTime = std::chrono::system_clock::now(); auto stampTime = std::chrono::system_clock::to_time_t(currentTime); tm newTime; localtime_s(&newTime, &stampTime); // 直接格式化到传入的缓冲区 strftime(time_buf, buf_size, " %Y/%m/%d %H:%M:%S", &newTime); } - 避免临时字符串拼接:在
Log函数中直接使用缓冲区输出,或者一次性拼接日志内容到预分配的缓冲区,减少多次字符串拼接带来的内存分配。 - 线程本地存储复用缓冲区:如果是多线程场景,可以用线程本地存储(
thread_local)的缓冲区,每个线程复用一块内存,既避免分配,又保证线程安全。
内容的提问来源于stack exchange,提问作者user24287404
相关产品推荐
相关产品推荐

