From 58b9fa88198eecc224597e52d8bbd7f833fca63b Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 12 May 2017 17:01:25 +0200 Subject: Completely shortcut the stream evaluation if we're not going to use the output Serializing the data is the expensive part, so we want to completely avoid that for the noisier part if we're not going to use it. Additionally we're now using a stringbuilder for the debugarea to try to further improve the situation with temporary memory allocations. --- common/log.cpp | 37 ++++++++++++++++++++++++------------- common/log.h | 5 ++++- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/common/log.cpp b/common/log.cpp index d1a3a37..5dfb872 100644 --- a/common/log.cpp +++ b/common/log.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace Sink::Log; @@ -315,13 +316,24 @@ static QByteArray getFileName(const char *file) return filename.split('.').first(); } -bool isFiltered(DebugLevel debugLevel, const QByteArray &fullDebugArea) +static QString assembleDebugArea(const char *debugArea, const char *debugComponent, const char *file) +{ + if (sPrimaryComponent.isEmpty()) { + sPrimaryComponent = getProgramName(); + } + //Using stringbuilder for fewer allocations + return QLatin1String{sPrimaryComponent} % QLatin1String{"."} % + (debugComponent ? (QLatin1String{debugComponent} + QLatin1String{"."}) : QLatin1String{""}) % + (debugArea ? QLatin1String{debugArea} : QLatin1String{getFileName(file)}); +} + +static bool isFiltered(DebugLevel debugLevel, const QByteArray &fullDebugArea) { if (debugLevel < debugOutputLevel()) { return true; } - auto areas = debugOutputFilter(Sink::Log::Area); - if (debugLevel <= Sink::Log::Trace && !areas.isEmpty()) { + const auto areas = debugOutputFilter(Sink::Log::Area); + if ((debugLevel <= Sink::Log::Trace) && !areas.isEmpty()) { if (!containsItemStartingWith(fullDebugArea, areas)) { return true; } @@ -329,19 +341,18 @@ bool isFiltered(DebugLevel debugLevel, const QByteArray &fullDebugArea) return false; } -QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, const char *function, const char *debugArea, const char *debugComponent) +bool Sink::Log::isFiltered(DebugLevel debugLevel, const char *debugArea, const char *debugComponent, const char *file) { - if (sPrimaryComponent.isEmpty()) { - sPrimaryComponent = getProgramName(); - } - const QByteArray fullDebugArea = sPrimaryComponent + "." + - (debugComponent ? (QByteArray{debugComponent} + ".") : "") + - (debugArea ? QByteArray{debugArea} : getFileName(file)); + return isFiltered(debugLevel, assembleDebugArea(debugArea, debugComponent, file).toLatin1()); +} +QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, const char *function, const char *debugArea, const char *debugComponent) +{ + const auto fullDebugArea = assembleDebugArea(debugArea, debugComponent, file); collectDebugArea(fullDebugArea); static NullStream nullstream; - if (isFiltered(debugLevel, fullDebugArea)) { + if (isFiltered(debugLevel, fullDebugArea.toLatin1())) { return QDebug(&nullstream); } @@ -391,12 +402,12 @@ QDebug Sink::Log::debugStream(DebugLevel debugLevel, int line, const char *file, } static std::atomic maxDebugAreaSize{25}; maxDebugAreaSize = qMax(fullDebugArea.size(), maxDebugAreaSize.load()); - output += QString(" %1 ").arg(QString{fullDebugArea}.leftJustified(maxDebugAreaSize, ' ', false)); + output += QString(" %1 ").arg(fullDebugArea.leftJustified(maxDebugAreaSize, ' ', false)); if (useColor) { output += resetColor; } if (showFunction) { - output += QString(" %3").arg(QString{fullDebugArea}.leftJustified(25, ' ', true)); + output += QString(" %3").arg(fullDebugArea.leftJustified(25, ' ', true)); } if (showLocation) { const auto filename = QString::fromLatin1(file).split('/').last(); diff --git a/common/log.h b/common/log.h index be5a508..8266fdb 100644 --- a/common/log.h +++ b/common/log.h @@ -85,12 +85,15 @@ SINK_EXPORT inline QDebug operator<<(QDebug d, const TraceTime &time) d << time.time << "[ms]"; return d; } + +SINK_EXPORT bool isFiltered(DebugLevel debugLevel, const char *debugArea, const char *debugComponent, const char *file); + } } static const char *getComponentName() { return nullptr; } -#define SINK_DEBUG_STREAM_IMPL(LEVEL, AREA, COMPONENT) Sink::Log::debugStream(LEVEL, __LINE__, __FILE__, Q_FUNC_INFO, AREA, COMPONENT) +#define SINK_DEBUG_STREAM_IMPL(LEVEL, AREA, COMPONENT) if (!Sink::Log::isFiltered(LEVEL, AREA, COMPONENT, __FILE__)) Sink::Log::debugStream(LEVEL, __LINE__, __FILE__, Q_FUNC_INFO, AREA, COMPONENT) #define Trace_area(AREA) SINK_DEBUG_STREAM_IMPL(Sink::Log::DebugLevel::Trace, AREA, nullptr) #define Log_area(AREA) SINK_DEBUG_STREAM_IMPL(Sink::Log::DebugLevel::Log, AREA, nullptr) -- cgit v1.2.3