From 6da58a6871d1b53c2cc38de04acd19fb7f84fc64 Mon Sep 17 00:00:00 2001 From: Ivan Savenko <saven.ivan@gmail.com> Date: Mon, 23 Dec 2024 21:24:00 +0000 Subject: [PATCH] Fixes excessive logging causing RMG slowdown - Do not apply formatting on log entries that will be discarded due to high log level - Do not log incorrect access to visitablePos due to its numerous use by RMG --- include/vstd/CLoggerBase.h | 22 +++++++++++++--------- lib/logging/CLogger.cpp | 15 +++++++++------ lib/logging/CLogger.h | 4 ++-- lib/mapObjects/CGObjectInstance.cpp | 8 ++++---- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/include/vstd/CLoggerBase.h b/include/vstd/CLoggerBase.h index a1cf6edba..4408a4cd8 100644 --- a/include/vstd/CLoggerBase.h +++ b/include/vstd/CLoggerBase.h @@ -58,6 +58,7 @@ public: virtual void log(ELogLevel::ELogLevel level, const std::string & message) const = 0; virtual void log(ELogLevel::ELogLevel level, const boost::format & fmt) const = 0; + virtual ELogLevel::ELogLevel getEffectiveLevel() const = 0; /// Returns true if a debug/trace log message will be logged, false if not. /// Useful if performance is important and concatenating the log message is a expensive task. @@ -67,16 +68,19 @@ public: template<typename T, typename ... Args> void log(ELogLevel::ELogLevel level, const std::string & format, T t, Args ... args) const { - try + if (getEffectiveLevel() <= level) { - boost::format fmt(format); - makeFormat(fmt, t, args...); - log(level, fmt); - } - catch(...) - { - log(ELogLevel::ERROR, "Log formatting failed, format was:"); - log(ELogLevel::ERROR, format); + try + { + boost::format fmt(format); + makeFormat(fmt, t, args...); + log(level, fmt); + } + catch(...) + { + log(ELogLevel::ERROR, "Log formatting failed, format was:"); + log(ELogLevel::ERROR, format); + } } } diff --git a/lib/logging/CLogger.cpp b/lib/logging/CLogger.cpp index e33c6425e..3968068b3 100644 --- a/lib/logging/CLogger.cpp +++ b/lib/logging/CLogger.cpp @@ -146,13 +146,16 @@ void CLogger::log(ELogLevel::ELogLevel level, const std::string & message) const void CLogger::log(ELogLevel::ELogLevel level, const boost::format & fmt) const { - try + if (getEffectiveLevel() <= level) { - log(level, fmt.str()); - } - catch(...) - { - log(ELogLevel::ERROR, "Invalid log format!"); + try + { + log(level, fmt.str()); + } + catch (...) + { + log(ELogLevel::ERROR, "Invalid log format!"); + } } } diff --git a/lib/logging/CLogger.h b/lib/logging/CLogger.h index 22c3035f1..654f5bf95 100644 --- a/lib/logging/CLogger.h +++ b/lib/logging/CLogger.h @@ -46,7 +46,7 @@ private: /// The logger is used to log messages to certain targets of a specific domain/name. /// It is thread-safe and can be used concurrently by several threads. -class DLL_LINKAGE CLogger: public vstd::CLoggerBase +class DLL_LINKAGE CLogger final: public vstd::CLoggerBase { public: ELogLevel::ELogLevel getLevel() const; @@ -70,7 +70,7 @@ public: private: explicit CLogger(const CLoggerDomain & domain); - inline ELogLevel::ELogLevel getEffectiveLevel() const; /// Returns the log level applied on this logger whether directly or indirectly. + inline ELogLevel::ELogLevel getEffectiveLevel() const override; /// Returns the log level applied on this logger whether directly or indirectly. inline void callTargets(const LogRecord & record) const; CLoggerDomain domain; diff --git a/lib/mapObjects/CGObjectInstance.cpp b/lib/mapObjects/CGObjectInstance.cpp index 8511a9875..cfaab7462 100644 --- a/lib/mapObjects/CGObjectInstance.cpp +++ b/lib/mapObjects/CGObjectInstance.cpp @@ -217,8 +217,8 @@ int CGObjectInstance::getSightRadius() const int3 CGObjectInstance::getVisitableOffset() const { - if (!isVisitable()) - logGlobal->debug("Attempt to access visitable offset on a non-visitable object!"); +// if (!isVisitable()) +// logGlobal->debug("Attempt to access visitable offset on a non-visitable object!"); return appearance->getVisitableOffset(); } @@ -317,8 +317,8 @@ void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const int3 CGObjectInstance::visitablePos() const { - if (!isVisitable()) - logGlobal->debug("Attempt to access visitable position on a non-visitable object!"); +// if (!isVisitable()) +// logGlobal->debug("Attempt to access visitable position on a non-visitable object!"); return pos - getVisitableOffset(); }