Cache std::ostringstream between assertions.

This is not thread safe, but I think that was already true of Catch.
The construction/destruction of the std::ostringstream is where the
vast majority of time is spent per assertion.  A simple test of
100000000 CHECK()s is reduced from around 60s to 7.4s
This commit is contained in:
Neal Coombes 2017-06-23 11:31:17 -05:00 committed by Martin Hořeňovský
parent a6cdcd43aa
commit 396ecf6021
2 changed files with 13 additions and 6 deletions

View File

@ -47,7 +47,7 @@ namespace Catch {
template<typename T>
ResultBuilder& operator << ( T const& value ) {
m_stream.oss << value;
m_stream().oss << value;
return *this;
}
@ -80,7 +80,12 @@ namespace Catch {
private:
AssertionInfo m_assertionInfo;
AssertionResultData m_data;
CopyableStream m_stream;
static CopyableStream &m_stream()
{
static CopyableStream s;
return s;
}
bool m_shouldDebugBreak;
bool m_shouldThrow;

View File

@ -27,12 +27,14 @@ namespace Catch {
m_shouldDebugBreak( false ),
m_shouldThrow( false ),
m_guardException( false )
{}
{
m_stream().oss.str("");
}
ResultBuilder::~ResultBuilder() {
#if defined(CATCH_CONFIG_FAST_COMPILE)
if ( m_guardException ) {
m_stream.oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
m_stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
captureResult( ResultWas::ThrewException );
getCurrentContext().getResultCapture()->exceptionEarlyReported();
}
@ -55,7 +57,7 @@ namespace Catch {
void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
m_assertionInfo.resultDisposition = resultDisposition;
m_stream.oss << Catch::translateActiveException();
m_stream().oss << Catch::translateActiveException();
captureResult( ResultWas::ThrewException );
}
@ -143,7 +145,7 @@ namespace Catch {
data.negate( expr.isBinaryExpression() );
}
data.message = m_stream.oss.str();
data.message = m_stream().oss.str();
data.decomposedExpression = &expr; // for lazy reconstruction
return AssertionResult( m_assertionInfo, data );
}