From 3b7511e5644dd74e2fb30b4a86769c07ccde88c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 14 Jan 2017 21:55:37 +0100 Subject: [PATCH 1/7] First commit of benchmarks for Catch runtime perf. So far its very much a WIP with some problems that are known already and not very representative tests. --- CMakeLists.txt | 8 +++ projects/Benchmark/BenchMain.cpp | 2 + projects/Benchmark/StringificationBench.cpp | 39 +++++++++++++ projects/Benchmark/readme.txt | 4 ++ ...cdddd43ba4df9e4846630be6a6a7bd85a07.result | 3 + scripts/runner.py | 56 +++++++++++++++++++ 6 files changed, 112 insertions(+) create mode 100644 projects/Benchmark/BenchMain.cpp create mode 100644 projects/Benchmark/StringificationBench.cpp create mode 100644 projects/Benchmark/readme.txt create mode 100644 projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result create mode 100644 scripts/runner.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 48ae6945..016d14b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON) # define some folders set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest) +set(BENCHMARK_DIR ${CATCH_DIR}/projects/Benchmark) set(HEADER_DIR ${CATCH_DIR}/include) if(USE_CPP11) @@ -161,13 +162,20 @@ set(HEADERS ${HEADER_DIR}/reporters/catch_reporter_xml.hpp ) +set(BENCH_SOURCES + ${BENCHMARK_DIR}/BenchMain.cpp + ${BENCHMARK_DIR}/StringificationBench.cpp + ) + # Provide some groupings for IDEs SOURCE_GROUP("Tests" FILES ${TEST_SOURCES}) SOURCE_GROUP("Surrogates" FILES ${IMPL_SOURCES}) +SOURCE_GROUP("Benchmarks" FILES ${BENCH_SOURCES}) # configure the executable include_directories(${HEADER_DIR}) add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS}) +add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS}) # configure unit tests via CTest enable_testing() diff --git a/projects/Benchmark/BenchMain.cpp b/projects/Benchmark/BenchMain.cpp new file mode 100644 index 00000000..0c7c351f --- /dev/null +++ b/projects/Benchmark/BenchMain.cpp @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include "catch.hpp" diff --git a/projects/Benchmark/StringificationBench.cpp b/projects/Benchmark/StringificationBench.cpp new file mode 100644 index 00000000..67f36685 --- /dev/null +++ b/projects/Benchmark/StringificationBench.cpp @@ -0,0 +1,39 @@ +#include "catch.hpp" + +#include + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE("Successful tests -- REQUIRE", "[Success]") { + const size_t sz = 1 * 1024 * 1024; + + + std::vector vec; vec.reserve(sz); + for (size_t i = 0; i < sz; ++i){ + vec.push_back(i); + REQUIRE(vec.back() == i); + } +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE("Successful tests -- CHECK", "[Success]") { + const size_t sz = 1 * 1024 * 1024; + + + std::vector vec; vec.reserve(sz); + for (size_t i = 0; i < sz; ++i){ + vec.push_back(i); + CHECK(vec.back() == i); + } +} + +/////////////////////////////////////////////////////////////////////////////// +TEST_CASE("Unsuccessful tests -- CHECK", "[Failure]") { + const size_t sz = 128 * 1024; + + + std::vector vec; vec.reserve(sz); + for (size_t i = 0; i < sz; ++i){ + vec.push_back(i); + CHECK(vec.size() == i); + } +} diff --git a/projects/Benchmark/readme.txt b/projects/Benchmark/readme.txt new file mode 100644 index 00000000..c4d2fabd --- /dev/null +++ b/projects/Benchmark/readme.txt @@ -0,0 +1,4 @@ +This is very much a work in progress. +The past results are standardized to a developer's machine, +the benchmarking script is basic and there are only 3 benchmarks, +but this should get better in time. For now, at least there is something to go by. diff --git a/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result b/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result new file mode 100644 index 00000000..4b6fc659 --- /dev/null +++ b/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result @@ -0,0 +1,3 @@ +Successful tests -- CHECK: median: 3.38116 (s), stddev: 0.11567366292001534 (s) +Successful tests -- REQUIRE: median: 3.479955 (s), stddev: 0.16295972890734556 (s) +Unsuccessful tests -- CHECK: median: 1.966895 (s), stddev: 0.06323488524716572 (s) diff --git a/scripts/runner.py b/scripts/runner.py new file mode 100644 index 00000000..dc753cf0 --- /dev/null +++ b/scripts/runner.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +import subprocess, os, sys +import xml.etree.ElementTree as ET +from collections import defaultdict +from statistics import median, stdev +from datetime import datetime + +def get_commit_hash(): + res = subprocess.run('git rev-parse HEAD'.split(), check=True, stdout=subprocess.PIPE, universal_newlines=True) + return res.stdout.strip() + +if len(sys.argv) < 2: + print('Usage: {} benchmark-binary'.format(sys.argv[0])) + exit(1) + + +num_runs = 10 +data = defaultdict(list) + + +def parse_file(file): + + def recursive_search(node): + if node.tag == 'TestCase': + results = node.find('OverallResult') + time = results.get('durationInSeconds') + data[node.get('name')].append(float(time)) + elif node.tag in ('Group', 'Catch'): + for child in node: + recursive_search(child) + + tree = ET.parse(file) + recursive_search(tree.getroot()) + +def run_benchmarks(binary): + call = [binary] + '-d yes -r xml -o'.split() + for i in range(num_runs): + file = 'temp{}.xml'.format(i) + print('Run number {}'.format(i)) + subprocess.run(call + [file]) + parse_file(file) + # Remove file right after parsing, because benchmark output can be big + os.remove(file) + + +# Run benchmarks +run_benchmarks(sys.argv[1]) + +result_file = '{:%Y-%m-%dT%H-%M-%S}-{}.result'.format(datetime.now(), get_commit_hash()) + + +print('Writing results to {}'.format(result_file)) +with open(result_file, 'w') as file: + for k in sorted(data): + file.write('{}: median: {} (s), stddev: {} (s)\n'.format(k, median(data[k]), stdev(data[k]))) From a1e9b841ff500b2f39ccfd4193ae450cb653da05 Mon Sep 17 00:00:00 2001 From: Mickey Rose Date: Mon, 9 Jan 2017 13:23:10 +0100 Subject: [PATCH 2/7] lazily stringify expressions --- include/internal/catch_assertionresult.h | 57 +++++++- include/internal/catch_assertionresult.hpp | 10 +- include/internal/catch_capture.hpp | 8 +- include/internal/catch_expression_lhs.hpp | 143 +++++++++++++++------ include/internal/catch_result_builder.h | 32 ++--- include/internal/catch_result_builder.hpp | 70 ++++------ include/reporters/catch_reporter_bases.hpp | 13 ++ 7 files changed, 223 insertions(+), 110 deletions(-) diff --git a/include/internal/catch_assertionresult.h b/include/internal/catch_assertionresult.h index 99b3a7c3..e2b979f8 100644 --- a/include/internal/catch_assertionresult.h +++ b/include/internal/catch_assertionresult.h @@ -13,6 +13,27 @@ namespace Catch { + struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; + + struct DecomposedExpression + { + virtual ~DecomposedExpression() {} + virtual bool isBinaryExpression() const { + return false; + } + virtual void reconstructExpression( std::string& dest ) const = 0; + + // Only simple binary comparisons can be decomposed. + // If more complex check is required then wrap sub-expressions in parentheses. + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& ); + }; + struct AssertionInfo { AssertionInfo() {} @@ -29,11 +50,41 @@ namespace Catch { struct AssertionResultData { - AssertionResultData() : resultType( ResultWas::Unknown ) {} + AssertionResultData() : decomposedExpression( CATCH_NULL ) + , resultType( ResultWas::Unknown ) + , negated( false ) + , parenthesized( false ) {} - std::string reconstructedExpression; + void negate( bool parenthesize ) { + negated = !negated; + parenthesized = parenthesize; + if( resultType == ResultWas::Ok ) + resultType = ResultWas::ExpressionFailed; + else if( resultType == ResultWas::ExpressionFailed ) + resultType = ResultWas::Ok; + } + + std::string const& reconstructExpression() const { + if( decomposedExpression != CATCH_NULL ) { + decomposedExpression->reconstructExpression( reconstructedExpression ); + if( parenthesized ) { + reconstructedExpression.insert( 0, 1, '(' ); + reconstructedExpression.append( 1, ')' ); + } + if( negated ) { + reconstructedExpression.insert( 0, 1, '!' ); + } + decomposedExpression = CATCH_NULL; + } + return reconstructedExpression; + } + + mutable DecomposedExpression const* decomposedExpression; + mutable std::string reconstructedExpression; std::string message; ResultWas::OfType resultType; + bool negated; + bool parenthesized; }; class AssertionResult { @@ -60,6 +111,8 @@ namespace Catch { std::string getMessage() const; SourceLineInfo getSourceInfo() const; std::string getTestMacroName() const; + void discardDecomposedExpression() const; + void expandDecomposedExpression() const; protected: AssertionInfo m_info; diff --git a/include/internal/catch_assertionresult.hpp b/include/internal/catch_assertionresult.hpp index bd59de9a..55fd8dd3 100644 --- a/include/internal/catch_assertionresult.hpp +++ b/include/internal/catch_assertionresult.hpp @@ -72,7 +72,7 @@ namespace Catch { } std::string AssertionResult::getExpandedExpression() const { - return m_resultData.reconstructedExpression; + return m_resultData.reconstructExpression(); } std::string AssertionResult::getMessage() const { @@ -86,6 +86,14 @@ namespace Catch { return m_info.macroName; } + void AssertionResult::discardDecomposedExpression() const { + m_resultData.decomposedExpression = CATCH_NULL; + } + + void AssertionResult::expandDecomposedExpression() const { + m_resultData.reconstructExpression(); + } + } // end namespace Catch #endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED diff --git a/include/internal/catch_capture.hpp b/include/internal/catch_capture.hpp index fa5835b8..12a70a0f 100644 --- a/include/internal/catch_capture.hpp +++ b/include/internal/catch_capture.hpp @@ -132,13 +132,7 @@ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \ try { \ - std::string matcherAsString = (matcher).toString(); \ - __catchResult \ - .setLhs( Catch::toString( arg ) ) \ - .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \ - .setOp( "matches" ) \ - .setResultType( (matcher).match( arg ) ); \ - __catchResult.captureExpression(); \ + __catchResult.captureMatch( arg, matcher, #matcher ); \ } catch( ... ) { \ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ } \ diff --git a/include/internal/catch_expression_lhs.hpp b/include/internal/catch_expression_lhs.hpp index 51b803e5..9670d2a1 100644 --- a/include/internal/catch_expression_lhs.hpp +++ b/include/internal/catch_expression_lhs.hpp @@ -14,90 +14,155 @@ namespace Catch { -// Wraps the LHS of an expression and captures the operator and RHS (if any) - -// wrapping them all in a ResultBuilder object -template -class ExpressionLhs { - ExpressionLhs& operator = ( ExpressionLhs const& ); -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - ExpressionLhs& operator = ( ExpressionLhs && ) = delete; -# endif +template +class BinaryExpression; +template +class MatchExpression; + +// Wraps the LHS of an expression and overloads comparison operators +// for also capturing those and RHS (if any) +template +class ExpressionLhs : public DecomposedExpression { public: - ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {} -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - ExpressionLhs( ExpressionLhs const& ) = default; - ExpressionLhs( ExpressionLhs && ) = default; -# endif + ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {} template - ResultBuilder& operator == ( RhsT const& rhs ) { + BinaryExpression + operator == ( RhsT const& rhs ) const { return captureExpression( rhs ); } template - ResultBuilder& operator != ( RhsT const& rhs ) { + BinaryExpression + operator != ( RhsT const& rhs ) const { return captureExpression( rhs ); } template - ResultBuilder& operator < ( RhsT const& rhs ) { + BinaryExpression + operator < ( RhsT const& rhs ) const { return captureExpression( rhs ); } template - ResultBuilder& operator > ( RhsT const& rhs ) { + BinaryExpression + operator > ( RhsT const& rhs ) const { return captureExpression( rhs ); } template - ResultBuilder& operator <= ( RhsT const& rhs ) { + BinaryExpression + operator <= ( RhsT const& rhs ) const { return captureExpression( rhs ); } template - ResultBuilder& operator >= ( RhsT const& rhs ) { + BinaryExpression + operator >= ( RhsT const& rhs ) const { return captureExpression( rhs ); } - ResultBuilder& operator == ( bool rhs ) { + BinaryExpression operator == ( bool rhs ) const { return captureExpression( rhs ); } - ResultBuilder& operator != ( bool rhs ) { + BinaryExpression operator != ( bool rhs ) const { return captureExpression( rhs ); } void endExpression() { - bool value = m_lhs ? true : false; + m_truthy = m_lhs ? true : false; m_rb - .setLhs( Catch::toString( value ) ) - .setResultType( value ) - .endExpression(); + .setResultType( m_truthy ) + .endExpression( *this ); } - // Only simple binary expressions are allowed on the LHS. - // If more complex compositions are required then place the sub expression in parentheses - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + dest = Catch::toString( m_truthy ); + } private: template - ResultBuilder& captureExpression( RhsT const& rhs ) { - return m_rb - .setResultType( Internal::compare( m_lhs, rhs ) ) - .setLhs( Catch::toString( m_lhs ) ) - .setRhs( Catch::toString( rhs ) ) - .setOp( Internal::OperatorTraits::getName() ); + BinaryExpression captureExpression( RhsT& rhs ) const { + return BinaryExpression( m_rb, m_lhs, rhs ); + } + + template + BinaryExpression captureExpression( bool rhs ) const { + return BinaryExpression( m_rb, m_lhs, rhs ); } private: ResultBuilder& m_rb; T m_lhs; + bool m_truthy; +}; + +template +class BinaryExpression : public DecomposedExpression { +public: + BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs ) + : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {} + + void endExpression() const { + m_rb + .setResultType( Internal::compare( m_lhs, m_rhs ) ) + .endExpression( *this ); + } + + virtual bool isBinaryExpression() const CATCH_OVERRIDE { + return true; + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + std::string lhs = Catch::toString( m_lhs ); + std::string rhs = Catch::toString( m_rhs ); + char delim = lhs.size() + rhs.size() < 40 && + lhs.find('\n') == std::string::npos && + rhs.find('\n') == std::string::npos ? ' ' : '\n'; + dest.reserve( 7 + lhs.size() + rhs.size() ); + // 2 for spaces around operator + // 2 for operator + // 2 for parentheses (conditionally added later) + // 1 for negation (conditionally added later) + dest = lhs; + dest += delim; + dest += Internal::OperatorTraits::getName(); + dest += delim; + dest += rhs; + } + +private: + ResultBuilder& m_rb; + LhsT m_lhs; + RhsT m_rhs; +}; + +template +class MatchExpression : public DecomposedExpression { +public: + MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString ) + : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {} + + virtual bool isBinaryExpression() const CATCH_OVERRIDE { + return true; + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + std::string matcherAsString = m_matcher.toString(); + dest = Catch::toString( m_arg ); + dest += ' '; + if( matcherAsString == Detail::unprintableString ) + dest += m_matcherString; + else + dest += matcherAsString; + } + +private: + ArgT m_arg; + MatcherT m_matcher; + char const* m_matcherString; }; } // end namespace Catch diff --git a/include/internal/catch_result_builder.h b/include/internal/catch_result_builder.h index 89002660..f646685a 100644 --- a/include/internal/catch_result_builder.h +++ b/include/internal/catch_result_builder.h @@ -19,8 +19,6 @@ namespace Catch { template class ExpressionLhs; - struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; - struct CopyableStream { CopyableStream() {} CopyableStream( CopyableStream const& other ) { @@ -34,7 +32,7 @@ namespace Catch { std::ostringstream oss; }; - class ResultBuilder { + class ResultBuilder : public DecomposedExpression { public: ResultBuilder( char const* macroName, SourceLineInfo const& lineInfo, @@ -52,19 +50,15 @@ namespace Catch { return *this; } - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); - ResultBuilder& setResultType( ResultWas::OfType result ); ResultBuilder& setResultType( bool result ); - ResultBuilder& setLhs( std::string const& lhs ); - ResultBuilder& setRhs( std::string const& rhs ); - ResultBuilder& setOp( std::string const& op ); - void endExpression(); + void endExpression( DecomposedExpression const& expr ); + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE; - std::string reconstructExpression() const; AssertionResult build() const; + AssertionResult build( DecomposedExpression const& expr ) const; void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); void captureResult( ResultWas::OfType resultType ); @@ -76,14 +70,12 @@ namespace Catch { bool shouldDebugBreak() const; bool allowThrows() const; + template + void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ); + private: AssertionInfo m_assertionInfo; AssertionResultData m_data; - struct ExprComponents { - ExprComponents() : testFalse( false ) {} - bool testFalse; - std::string lhs, rhs, op; - } m_exprComponents; CopyableStream m_stream; bool m_shouldDebugBreak; @@ -106,6 +98,14 @@ namespace Catch { return ExpressionLhs( *this, value ); } + template + inline void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, + char const* matcherString ) { + MatchExpression expr( arg, matcher, matcherString ); + setResultType( matcher.match( arg ) ); + endExpression( expr ); + } + } // namespace Catch #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED diff --git a/include/internal/catch_result_builder.hpp b/include/internal/catch_result_builder.hpp index bf2f8575..7bb2cdc2 100644 --- a/include/internal/catch_result_builder.hpp +++ b/include/internal/catch_result_builder.hpp @@ -41,22 +41,10 @@ namespace Catch { m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; return *this; } - ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) { - m_exprComponents.lhs = lhs; - return *this; - } - ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) { - m_exprComponents.rhs = rhs; - return *this; - } - ResultBuilder& ResultBuilder::setOp( std::string const& op ) { - m_exprComponents.op = op; - return *this; - } - void ResultBuilder::endExpression() { - m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition ); - captureExpression(); + void ResultBuilder::endExpression( DecomposedExpression const& expr ) { + AssertionResult result = build( expr ); + handleResult( result ); } void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { @@ -69,6 +57,7 @@ namespace Catch { setResultType( resultType ); captureExpression(); } + void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { if( expectedMessage.empty() ) captureExpectedException( Matchers::Impl::Generic::AllOf() ); @@ -78,7 +67,7 @@ namespace Catch { void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher const& matcher ) { - assert( m_exprComponents.testFalse == false ); + assert( !isFalseTest( m_assertionInfo.resultDisposition ) ); AssertionResultData data = m_data; data.resultType = ResultWas::Ok; data.reconstructedExpression = m_assertionInfo.capturedExpression; @@ -96,6 +85,7 @@ namespace Catch { AssertionResult result = build(); handleResult( result ); } + void ResultBuilder::handleResult( AssertionResult const& result ) { getResultCapture().assertionEnded( result ); @@ -107,6 +97,7 @@ namespace Catch { m_shouldThrow = true; } } + void ResultBuilder::react() { if( m_shouldThrow ) throw Catch::TestFailureException(); @@ -117,43 +108,32 @@ namespace Catch { AssertionResult ResultBuilder::build() const { - assert( m_data.resultType != ResultWas::Unknown ); + return build( *this ); + } + // CAVEAT: The returned AssertionResult stores a pointer to the argument expr, + // a temporary DecomposedExpression, which in turn holds references to + // operands, possibly temporary as well. + // It should immediately be passed to handleResult; if the expression + // needs to be reported, its string expansion must be composed before + // the temporaries are destroyed. + AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const + { + assert( m_data.resultType != ResultWas::Unknown ); AssertionResultData data = m_data; - // Flip bool results if testFalse is set - if( m_exprComponents.testFalse ) { - if( data.resultType == ResultWas::Ok ) - data.resultType = ResultWas::ExpressionFailed; - else if( data.resultType == ResultWas::ExpressionFailed ) - data.resultType = ResultWas::Ok; + // Flip bool results if FalseTest flag is set + if( isFalseTest( m_assertionInfo.resultDisposition ) ) { + data.negate( expr.isBinaryExpression() ); } data.message = m_stream.oss.str(); - data.reconstructedExpression = reconstructExpression(); - if( m_exprComponents.testFalse ) { - if( m_exprComponents.op == "" ) - data.reconstructedExpression = "!" + data.reconstructedExpression; - else - data.reconstructedExpression = "!(" + data.reconstructedExpression + ")"; - } + data.decomposedExpression = &expr; // for lazy reconstruction return AssertionResult( m_assertionInfo, data ); } - std::string ResultBuilder::reconstructExpression() const { - if( m_exprComponents.op == "" ) - return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.lhs; - else if( m_exprComponents.op == "matches" ) - return m_exprComponents.lhs + " " + m_exprComponents.rhs; - else if( m_exprComponents.op != "!" ) { - if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 && - m_exprComponents.lhs.find("\n") == std::string::npos && - m_exprComponents.rhs.find("\n") == std::string::npos ) - return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs; - else - return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs; - } - else - return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}"; + + void ResultBuilder::reconstructExpression( std::string& dest ) const { + dest = m_assertionInfo.capturedExpression; } } // end namespace Catch diff --git a/include/reporters/catch_reporter_bases.hpp b/include/reporters/catch_reporter_bases.hpp index cfc28f29..0c13a16b 100644 --- a/include/reporters/catch_reporter_bases.hpp +++ b/include/reporters/catch_reporter_bases.hpp @@ -170,6 +170,12 @@ namespace Catch { assert( !m_sectionStack.empty() ); SectionNode& sectionNode = *m_sectionStack.back(); sectionNode.assertions.push_back( assertionStats ); + // AssertionResult holds a pointer to a temporary DecomposedExpression, + // which getExpandedExpression() calls to build the expression string. + // Our section stack copy of the assertionResult will likely outlive the + // temporary, so it must be expanded or discarded now to avoid calling + // a destroyed object later. + prepareExpandedExpression( sectionNode.assertions.back().assertionResult ); return true; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { @@ -204,6 +210,13 @@ namespace Catch { virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} + virtual void prepareExpandedExpression( AssertionResult& result ) const { + if( result.isOk() ) + result.discardDecomposedExpression(); + else + result.expandDecomposedExpression(); + } + Ptr m_config; std::ostream& stream; std::vector m_assertions; From 877fd523bcf5eef07970bebf603b2c3553877bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 14 Jan 2017 22:51:44 +0100 Subject: [PATCH 3/7] Added benchmark with Mickey Rose's improvements. --- ...14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result diff --git a/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result b/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result new file mode 100644 index 00000000..98c84601 --- /dev/null +++ b/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result @@ -0,0 +1,3 @@ +Successful tests -- CHECK: median: 1.30312 (s), stddev: 0.08759818557862176 (s) +Successful tests -- REQUIRE: median: 1.341535 (s), stddev: 0.1479193390143576 (s) +Unsuccessful tests -- CHECK: median: 1.967755 (s), stddev: 0.07921104121269959 (s) From 3b98a0166f7b7196eba2ad518174d1a77165166d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 15 Jan 2017 09:41:33 +0100 Subject: [PATCH 4/7] Various small string usage performance improvements. * Empty strings are now direct constructed as `std::string()`, not as empty string literals. * `startsWith` and `endsWith` no longer construct new a string. This should be an improvement for libstdc++ when using older standards, as it doesn't use SSO but COW and thus even short strings are expensive to first create. * Various places now use char literal instead of string literals containing single char. ** `startsWith` and `endsWith` now also have overload that takes single char. Generally the performance improvements under VS2015 are small, as going from short string to char is mostly meaningless because of SSO (Catch doesn't push string handling that hard) and previous commit removed most string handling if tests pass, which is the expect case. --- include/internal/catch_commandline.hpp | 6 +++--- include/internal/catch_common.h | 3 +++ include/internal/catch_common.hpp | 21 ++++++++++++++----- include/internal/catch_list.hpp | 6 +++--- include/internal/catch_matchers.hpp | 2 +- .../internal/catch_reporter_registrars.hpp | 2 +- include/internal/catch_result_builder.h | 2 +- include/internal/catch_run_context.hpp | 12 +++++------ include/internal/catch_tag_alias_registry.hpp | 4 ++-- include/internal/catch_test_case_info.hpp | 2 +- .../catch_test_case_registry_impl.hpp | 6 +++--- include/internal/catch_tostring.hpp | 8 +++---- include/internal/catch_wildcard_pattern.hpp | 4 ++-- include/internal/catch_xmlwriter.hpp | 2 +- 14 files changed, 47 insertions(+), 33 deletions(-) diff --git a/include/internal/catch_commandline.hpp b/include/internal/catch_commandline.hpp index 89eced34..e7ee6e82 100644 --- a/include/internal/catch_commandline.hpp +++ b/include/internal/catch_commandline.hpp @@ -85,10 +85,10 @@ namespace Catch { std::string line; while( std::getline( f, line ) ) { line = trim(line); - if( !line.empty() && !startsWith( line, "#" ) ) { - if( !startsWith( line, "\"" ) ) + if( !line.empty() && !startsWith( line, '#' ) ) { + if( !startsWith( line, '"' ) ) line = "\"" + line + "\""; - addTestOrTags( config, line + "," ); + addTestOrTags( config, line + ',' ); } } } diff --git a/include/internal/catch_common.h b/include/internal/catch_common.h index 9e742bc4..43f46a98 100644 --- a/include/internal/catch_common.h +++ b/include/internal/catch_common.h @@ -79,7 +79,10 @@ namespace Catch { } bool startsWith( std::string const& s, std::string const& prefix ); + bool startsWith( std::string const& s, char prefix ); bool endsWith( std::string const& s, std::string const& suffix ); + bool endsWith( std::string const& s, char suffix ); + bool contains( std::string const& s, std::string const& infix ); bool contains( std::string const& s, std::string const& infix ); void toLowerInPlace( std::string& s ); std::string toLower( std::string const& s ); diff --git a/include/internal/catch_common.hpp b/include/internal/catch_common.hpp index 7ad5b1ca..f4006c72 100644 --- a/include/internal/catch_common.hpp +++ b/include/internal/catch_common.hpp @@ -10,17 +10,28 @@ #include "catch_common.h" +#include + namespace Catch { bool startsWith( std::string const& s, std::string const& prefix ) { - return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix; + return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); + } + bool startsWith( std::string const& s, char prefix ) { + return !s.empty() && s.front() == prefix; } bool endsWith( std::string const& s, std::string const& suffix ) { - return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix; + return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); + } + bool endsWith( std::string const& s, char suffix ) { + return !s.empty() && s.back() == suffix; } bool contains( std::string const& s, std::string const& infix ) { return s.find( infix ) != std::string::npos; } + bool contains( std::string const& s, char infix ) { + return s.find(infix); + } char toLowerCh(char c) { return static_cast( ::tolower( c ) ); } @@ -37,7 +48,7 @@ namespace Catch { std::string::size_type start = str.find_first_not_of( whitespaceChars ); std::string::size_type end = str.find_last_not_of( whitespaceChars ); - return start != std::string::npos ? str.substr( start, 1+end-start ) : ""; + return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); } bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { @@ -95,9 +106,9 @@ namespace Catch { std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { #ifndef __GNUG__ - os << info.file << "(" << info.line << ")"; + os << info.file << '(' << info.line << ')'; #else - os << info.file << ":" << info.line; + os << info.file << ':' << info.line; #endif return os; } diff --git a/include/internal/catch_list.hpp b/include/internal/catch_list.hpp index f83827ee..72f38bba 100644 --- a/include/internal/catch_list.hpp +++ b/include/internal/catch_list.hpp @@ -51,9 +51,9 @@ namespace Catch { } if( !config.testSpec().hasFilters() ) - Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl; + Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl; else - Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl; + Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl; return matchedTests; } @@ -68,7 +68,7 @@ namespace Catch { ++it ) { matchedTests++; TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); - if( startsWith( testCaseInfo.name, "#" ) ) + if( startsWith( testCaseInfo.name, '#' ) ) Catch::cout() << "\"" << testCaseInfo.name << "\"" << std::endl; else Catch::cout() << testCaseInfo.name << std::endl; diff --git a/include/internal/catch_matchers.hpp b/include/internal/catch_matchers.hpp index ab8fec15..61234c45 100644 --- a/include/internal/catch_matchers.hpp +++ b/include/internal/catch_matchers.hpp @@ -184,7 +184,7 @@ namespace Matchers { { return m_caseSensitivity == CaseSensitive::No ? " (case insensitive)" - : ""; + : std::string(); } CaseSensitive::Choice m_caseSensitivity; std::string m_str; diff --git a/include/internal/catch_reporter_registrars.hpp b/include/internal/catch_reporter_registrars.hpp index 7bd7b610..4d5557e1 100644 --- a/include/internal/catch_reporter_registrars.hpp +++ b/include/internal/catch_reporter_registrars.hpp @@ -74,7 +74,7 @@ namespace Catch { return new T( config ); } virtual std::string getDescription() const { - return ""; + return std::string(); } }; diff --git a/include/internal/catch_result_builder.h b/include/internal/catch_result_builder.h index f646685a..dfdffd5f 100644 --- a/include/internal/catch_result_builder.h +++ b/include/internal/catch_result_builder.h @@ -25,7 +25,7 @@ namespace Catch { oss << other.oss.str(); } CopyableStream& operator=( CopyableStream const& other ) { - oss.str(""); + oss.str(std::string()); oss << other.oss.str(); return *this; } diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp index d37bdba1..30929625 100644 --- a/include/internal/catch_run_context.hpp +++ b/include/internal/catch_run_context.hpp @@ -146,7 +146,7 @@ namespace Catch { m_messages.clear(); // Reset working state - m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); + m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); m_lastResult = result; } @@ -217,7 +217,7 @@ namespace Catch { virtual std::string getCurrentTestName() const { return m_activeTestCase ? m_activeTestCase->getTestCaseInfo().name - : ""; + : std::string(); } virtual const AssertionResult* getLastResult() const { @@ -247,11 +247,11 @@ namespace Catch { deltaTotals.testCases.failed = 1; m_reporter->testCaseEnded( TestCaseStats( testInfo, deltaTotals, - "", - "", + std::string(), + std::string(), false ) ); m_totals.testCases.failed++; - testGroupEnded( "", m_totals, 1, 1 ); + testGroupEnded( std::string(), m_totals, 1, 1 ); m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); } @@ -270,7 +270,7 @@ namespace Catch { Counts prevAssertions = m_totals.assertions; double duration = 0; try { - m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); + m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, std::string(), ResultDisposition::Normal ); seedRng( *m_config ); diff --git a/include/internal/catch_tag_alias_registry.hpp b/include/internal/catch_tag_alias_registry.hpp index e5ad11b2..a1fa56b9 100644 --- a/include/internal/catch_tag_alias_registry.hpp +++ b/include/internal/catch_tag_alias_registry.hpp @@ -43,7 +43,7 @@ namespace Catch { void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { - if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) { + if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) { std::ostringstream oss; oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo; throw std::domain_error( oss.str().c_str() ); @@ -51,7 +51,7 @@ namespace Catch { if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { std::ostringstream oss; oss << "error: tag alias, \"" << alias << "\" already registered.\n" - << "\tFirst seen at " << find(alias)->lineInfo << "\n" + << "\tFirst seen at " << find(alias)->lineInfo << '\n' << "\tRedefined at " << lineInfo; throw std::domain_error( oss.str().c_str() ); } diff --git a/include/internal/catch_test_case_info.hpp b/include/internal/catch_test_case_info.hpp index 90f53411..d3212902 100644 --- a/include/internal/catch_test_case_info.hpp +++ b/include/internal/catch_test_case_info.hpp @@ -16,7 +16,7 @@ namespace Catch { inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { - if( startsWith( tag, "." ) || + if( startsWith( tag, '.' ) || tag == "hide" || tag == "!hide" ) return TestCaseInfo::IsHidden; diff --git a/include/internal/catch_test_case_registry_impl.hpp b/include/internal/catch_test_case_registry_impl.hpp index 33169b26..0565b54a 100644 --- a/include/internal/catch_test_case_registry_impl.hpp +++ b/include/internal/catch_test_case_registry_impl.hpp @@ -78,7 +78,7 @@ namespace Catch { ss << Colour( Colour::Red ) << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n" - << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n" + << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n' << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl; throw std::runtime_error(ss.str()); @@ -110,7 +110,7 @@ namespace Catch { virtual void registerTest( TestCase const& testCase ) { std::string name = testCase.getTestCaseInfo().name; - if( name == "" ) { + if( name.empty() ) { std::ostringstream oss; oss << "Anonymous test case " << ++m_unnamedCount; return registerTest( testCase.withName( oss.str() ) ); @@ -159,7 +159,7 @@ namespace Catch { inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { std::string className = classOrQualifiedMethodName; - if( startsWith( className, "&" ) ) + if( startsWith( className, '&' ) ) { std::size_t lastColons = className.rfind( "::" ); std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); diff --git a/include/internal/catch_tostring.hpp b/include/internal/catch_tostring.hpp index 0a20ee2d..0c4ed62f 100644 --- a/include/internal/catch_tostring.hpp +++ b/include/internal/catch_tostring.hpp @@ -102,7 +102,7 @@ std::string toString( int value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) - oss << " (0x" << std::hex << value << ")"; + oss << " (0x" << std::hex << value << ')'; return oss.str(); } @@ -110,7 +110,7 @@ std::string toString( unsigned long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) - oss << " (0x" << std::hex << value << ")"; + oss << " (0x" << std::hex << value << ')'; return oss.str(); } @@ -164,14 +164,14 @@ std::string toString( long long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) - oss << " (0x" << std::hex << value << ")"; + oss << " (0x" << std::hex << value << ')'; return oss.str(); } std::string toString( unsigned long long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) - oss << " (0x" << std::hex << value << ")"; + oss << " (0x" << std::hex << value << ')'; return oss.str(); } #endif diff --git a/include/internal/catch_wildcard_pattern.hpp b/include/internal/catch_wildcard_pattern.hpp index cd8b07e1..6ce66a4d 100644 --- a/include/internal/catch_wildcard_pattern.hpp +++ b/include/internal/catch_wildcard_pattern.hpp @@ -27,11 +27,11 @@ namespace Catch m_wildcard( NoWildcard ), m_pattern( adjustCase( pattern ) ) { - if( startsWith( m_pattern, "*" ) ) { + if( startsWith( m_pattern, '*' ) ) { m_pattern = m_pattern.substr( 1 ); m_wildcard = WildcardAtStart; } - if( endsWith( m_pattern, "*" ) ) { + if( endsWith( m_pattern, '*' ) ) { m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); } diff --git a/include/internal/catch_xmlwriter.hpp b/include/internal/catch_xmlwriter.hpp index c181e10e..17f7064e 100644 --- a/include/internal/catch_xmlwriter.hpp +++ b/include/internal/catch_xmlwriter.hpp @@ -202,7 +202,7 @@ namespace Catch { XmlWriter& writeBlankLine() { ensureTagClosed(); - stream() << "\n"; + stream() << '\n'; return *this; } From 83f4b39680784e7ac6d8fd71ac8bc9541541385f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 15 Jan 2017 10:06:18 +0100 Subject: [PATCH 5/7] Added benchmark for previous commit, added iterations to failure bench. --- include/internal/catch_common.hpp | 6 ++---- projects/Benchmark/StringificationBench.cpp | 2 +- ...09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result | 3 +++ 3 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result diff --git a/include/internal/catch_common.hpp b/include/internal/catch_common.hpp index f4006c72..2af51a12 100644 --- a/include/internal/catch_common.hpp +++ b/include/internal/catch_common.hpp @@ -10,21 +10,19 @@ #include "catch_common.h" -#include - namespace Catch { bool startsWith( std::string const& s, std::string const& prefix ) { return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); } bool startsWith( std::string const& s, char prefix ) { - return !s.empty() && s.front() == prefix; + return !s.empty() && s[0] == prefix; } bool endsWith( std::string const& s, std::string const& suffix ) { return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); } bool endsWith( std::string const& s, char suffix ) { - return !s.empty() && s.back() == suffix; + return !s.empty() && s[s.size()-1] == suffix; } bool contains( std::string const& s, std::string const& infix ) { return s.find( infix ) != std::string::npos; diff --git a/projects/Benchmark/StringificationBench.cpp b/projects/Benchmark/StringificationBench.cpp index 67f36685..4c81a577 100644 --- a/projects/Benchmark/StringificationBench.cpp +++ b/projects/Benchmark/StringificationBench.cpp @@ -28,7 +28,7 @@ TEST_CASE("Successful tests -- CHECK", "[Success]") { /////////////////////////////////////////////////////////////////////////////// TEST_CASE("Unsuccessful tests -- CHECK", "[Failure]") { - const size_t sz = 128 * 1024; + const size_t sz = 1024 * 1024; std::vector vec; vec.reserve(sz); diff --git a/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result b/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result new file mode 100644 index 00000000..fe6366b8 --- /dev/null +++ b/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result @@ -0,0 +1,3 @@ +Successful tests -- CHECK: median: 1.2982 (s), stddev: 0.019540648829214084 (s) +Successful tests -- REQUIRE: median: 1.30102 (s), stddev: 0.014758430547392974 (s) +Unsuccessful tests -- CHECK: median: 15.520199999999999 (s), stddev: 0.09536359426485094 (s) From 51107d7cbdd3a148298ac9f3fc02db3bd5fa513f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 16 Jan 2017 18:40:55 +0100 Subject: [PATCH 6/7] Added copyright headers to benchmark files. --- projects/Benchmark/BenchMain.cpp | 7 +++++++ projects/Benchmark/StringificationBench.cpp | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/projects/Benchmark/BenchMain.cpp b/projects/Benchmark/BenchMain.cpp index 0c7c351f..32ef4ed9 100644 --- a/projects/Benchmark/BenchMain.cpp +++ b/projects/Benchmark/BenchMain.cpp @@ -1,2 +1,9 @@ +/* + * Created by Martin on 16/01/2017. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + #define CATCH_CONFIG_MAIN #include "catch.hpp" diff --git a/projects/Benchmark/StringificationBench.cpp b/projects/Benchmark/StringificationBench.cpp index 4c81a577..1c14939b 100644 --- a/projects/Benchmark/StringificationBench.cpp +++ b/projects/Benchmark/StringificationBench.cpp @@ -1,3 +1,10 @@ +/* + * Created by Martin on 16/01/2017. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + #include "catch.hpp" #include From 99c2ea594c87b87c3a6e99343978d77d4042b70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Wed, 25 Jan 2017 22:55:11 +0100 Subject: [PATCH 7/7] Renamed measurement script for benchmarking --- scripts/{runner.py => benchmarkRunner.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/{runner.py => benchmarkRunner.py} (100%) diff --git a/scripts/runner.py b/scripts/benchmarkRunner.py similarity index 100% rename from scripts/runner.py rename to scripts/benchmarkRunner.py