From 8d74cc631c73c6124cd0c4e85b09d3e77fb79bda Mon Sep 17 00:00:00 2001 From: Julian Brost Date: Mon, 14 Jul 2025 13:37:36 +0200 Subject: [PATCH] Log: don't construct std::ostringstream for no-op messages This commit removes the existing m_IsNoOp bool and instead wraps the m_Buffer std::ostringstream into std::optional. Functionally, this is pretty much the same, with the exception that std::ostringstream is no longer constructed for messages that will be discarded later. --- lib/base/logger.cpp | 18 +++++++++++------- lib/base/logger.hpp | 12 ++++++++---- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/base/logger.cpp b/lib/base/logger.cpp index b3be523a8..f28a19bbd 100644 --- a/lib/base/logger.cpp +++ b/lib/base/logger.cpp @@ -247,21 +247,25 @@ void Logger::UpdateMinLogSeverity() Log::Log(LogSeverity severity, String facility, const String& message) : Log(severity, std::move(facility)) { - if (!m_IsNoOp) { - m_Buffer << message; - } + *this << message; } Log::Log(LogSeverity severity, String facility) - : m_Severity(severity), m_Facility(std::move(facility)), m_IsNoOp(severity < Logger::GetMinLogSeverity()) -{ } +{ + // Only fully initialize the object if it's actually going to be logged. + if (severity >= Logger::GetMinLogSeverity()) { + m_Severity = severity; + m_Facility = std::move(facility); + m_Buffer.emplace(); + } +} /** * Writes the message to the application's log. */ Log::~Log() { - if (m_IsNoOp) { + if (!m_Buffer) { return; } @@ -271,7 +275,7 @@ Log::~Log() entry.Facility = m_Facility; { - auto msg (m_Buffer.str()); + auto msg (m_Buffer->str()); msg.erase(msg.find_last_not_of("\n") + 1u); entry.Message = std::move(msg); diff --git a/lib/base/logger.hpp b/lib/base/logger.hpp index 0437ebf39..d7f30bcee 100644 --- a/lib/base/logger.hpp +++ b/lib/base/logger.hpp @@ -6,6 +6,7 @@ #include "base/atomic.hpp" #include "base/i2-base.hpp" #include "base/logger-ti.hpp" +#include #include #include @@ -121,8 +122,8 @@ public: template Log& operator<<(T&& val) { - if (!m_IsNoOp) { - m_Buffer << std::forward(val); + if (m_Buffer) { + *m_Buffer << std::forward(val); } return *this; @@ -131,8 +132,11 @@ public: private: LogSeverity m_Severity; String m_Facility; - std::ostringstream m_Buffer; - bool m_IsNoOp; + /** + * Stream for incrementally generating the log message. If the message will be discarded as it's level currently + * isn't logged, it will be empty as the stream doesn't need to be initialized in this case. + */ + std::optional m_Buffer; }; extern template Log& Log::operator<<(const Value&);