From 822c44a20395c6194d527110d59f7513a55b885c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 23 Dec 2023 16:06:30 +0100 Subject: [PATCH] Cleanup help string construction in Clara * Clara::Opt::getHelpColumns returns single item It could never return multiple items, but for some reason it was wrapping that single item in a vector. * Use ReusableStringStream in Clara * Reserve HelpColumns ahead of time * Use StringRef for descriptions in HelpColumn type The combination of these changes ends up removing about 7% (~200) of allocations when Catch2 has to prepare output for `-h`. --- src/catch2/internal/catch_clara.cpp | 13 +++++++------ src/catch2/internal/catch_clara.hpp | 7 ++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/catch2/internal/catch_clara.cpp b/src/catch2/internal/catch_clara.cpp index 4745eb89..9510fcc2 100644 --- a/src/catch2/internal/catch_clara.cpp +++ b/src/catch2/internal/catch_clara.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -173,8 +174,8 @@ namespace Catch { Opt::Opt(bool& ref) : ParserRefImpl(std::make_shared(ref)) {} - std::vector Opt::getHelpColumns() const { - std::ostringstream oss; + Detail::HelpColumns Opt::getHelpColumns() const { + ReusableStringStream oss; bool first = true; for (auto const& opt : m_optNames) { if (first) @@ -185,7 +186,7 @@ namespace Catch { } if (!m_hint.empty()) oss << " <" << m_hint << '>'; - return { { oss.str(), static_cast(m_description) } }; + return { oss.str(), m_description }; } bool Opt::isMatch(std::string const& optToken) const { @@ -310,9 +311,9 @@ namespace Catch { std::vector Parser::getHelpColumns() const { std::vector cols; + cols.reserve( m_options.size() ); for ( auto const& o : m_options ) { - auto childCols = o.getHelpColumns(); - cols.insert( cols.end(), childCols.begin(), childCols.end() ); + cols.push_back(o.getHelpColumns()); } return cols; } @@ -355,7 +356,7 @@ namespace Catch { .width( optWidth ) .indent( 2 ) + TextFlow::Spacer( 4 ) + - TextFlow::Column( cols.right ) + TextFlow::Column( static_cast(cols.descriptions) ) .width( consoleWidth - 7 - optWidth ); os << row << '\n'; } diff --git a/src/catch2/internal/catch_clara.hpp b/src/catch2/internal/catch_clara.hpp index d8c31c68..8f6a4e9e 100644 --- a/src/catch2/internal/catch_clara.hpp +++ b/src/catch2/internal/catch_clara.hpp @@ -164,7 +164,8 @@ namespace Catch { ResultType m_type; }; - template class ResultValueBase : public ResultBase { + template + class ResultValueBase : public ResultBase { public: auto value() const -> T const& { enforceOk(); @@ -286,7 +287,7 @@ namespace Catch { struct HelpColumns { std::string left; - std::string right; + StringRef descriptions; }; template @@ -571,7 +572,7 @@ namespace Catch { return *this; } - std::vector getHelpColumns() const; + Detail::HelpColumns getHelpColumns() const; bool isMatch(std::string const& optToken) const;