mirror of https://github.com/catchorg/Catch2.git
Report benchmark durations in natural units
(and extended StringRef to be able to report utf8 char lengths
This commit is contained in:
parent
4421672fb8
commit
519db85758
|
@ -64,6 +64,9 @@ namespace Catch {
|
||||||
auto String::size() const noexcept -> size_type {
|
auto String::size() const noexcept -> size_type {
|
||||||
return m_data->size;
|
return m_data->size;
|
||||||
}
|
}
|
||||||
|
auto String::numberOfCharacters() const noexcept -> size_type {
|
||||||
|
return StringRef( *this ).numberOfCharacters();
|
||||||
|
}
|
||||||
auto String::c_str() const noexcept -> char const* {
|
auto String::c_str() const noexcept -> char const* {
|
||||||
return m_data->chars;
|
return m_data->chars;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ namespace Catch {
|
||||||
|
|
||||||
auto empty() const noexcept -> bool;
|
auto empty() const noexcept -> bool;
|
||||||
auto size() const noexcept -> size_type;
|
auto size() const noexcept -> size_type;
|
||||||
|
auto numberOfCharacters() const noexcept -> size_type;
|
||||||
|
|
||||||
auto c_str() const noexcept -> char const*;
|
auto c_str() const noexcept -> char const*;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,23 @@ namespace Catch {
|
||||||
auto StringRef::size() const noexcept -> size_type {
|
auto StringRef::size() const noexcept -> size_type {
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
auto StringRef::numberOfCharacters() const noexcept -> size_type {
|
||||||
|
size_type noChars = m_size;
|
||||||
|
// Make adjustments for uft encodings
|
||||||
|
for( size_type i=0; i < m_size; ++i ) {
|
||||||
|
char c = m_start[i];
|
||||||
|
if( ( c & 0b11000000 ) == 0b11000000 ) {
|
||||||
|
if( ( c & 0b11100000 ) == 0b11000000 )
|
||||||
|
noChars--;
|
||||||
|
else if( ( c & 0b11110000 ) == 0b11100000 )
|
||||||
|
noChars-=2;
|
||||||
|
else if( ( c & 0b11111000 ) == 0b11110000 )
|
||||||
|
noChars-=3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return noChars;
|
||||||
|
}
|
||||||
|
|
||||||
auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> String {
|
auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> String {
|
||||||
StringBuilder buf;
|
StringBuilder buf;
|
||||||
buf.reserve( lhs.size() + rhs.size() );
|
buf.reserve( lhs.size() + rhs.size() );
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace Catch {
|
||||||
public: // named queries
|
public: // named queries
|
||||||
auto empty() const noexcept -> bool;
|
auto empty() const noexcept -> bool;
|
||||||
auto size() const noexcept -> size_type;
|
auto size() const noexcept -> size_type;
|
||||||
|
auto numberOfCharacters() const noexcept -> size_type;
|
||||||
auto c_str() const -> char const*;
|
auto c_str() const -> char const*;
|
||||||
|
|
||||||
public: // substrings and searches
|
public: // substrings and searches
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "../internal/catch_console_colour.hpp"
|
#include "../internal/catch_console_colour.hpp"
|
||||||
#include "../internal/catch_version.h"
|
#include "../internal/catch_version.h"
|
||||||
#include "../internal/catch_text.h"
|
#include "../internal/catch_text.h"
|
||||||
|
#include "../internal/catch_stringref.h"
|
||||||
|
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -82,6 +83,8 @@ namespace {
|
||||||
|
|
||||||
friend TablePrinter& operator << ( TablePrinter& tp, ColumnBreak ) {
|
friend TablePrinter& operator << ( TablePrinter& tp, ColumnBreak ) {
|
||||||
auto colStr = tp.m_oss.str();
|
auto colStr = tp.m_oss.str();
|
||||||
|
// This takes account of utf8 encodings
|
||||||
|
auto strSize = Catch::StringRef( colStr.c_str(), colStr.size() ).numberOfCharacters();
|
||||||
tp.m_oss.str("");
|
tp.m_oss.str("");
|
||||||
tp.open();
|
tp.open();
|
||||||
if( tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size()-1) ) {
|
if( tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size()-1) ) {
|
||||||
|
@ -93,8 +96,8 @@ namespace {
|
||||||
tp.m_currentColumn++;
|
tp.m_currentColumn++;
|
||||||
|
|
||||||
auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
|
auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
|
||||||
auto padding = ( colStr.size()+2 < static_cast<size_t>( colInfo.width ) )
|
auto padding = ( strSize+2 < static_cast<size_t>( colInfo.width ) )
|
||||||
? std::string( colInfo.width-(colStr.size()+2), ' ' )
|
? std::string( colInfo.width-(strSize+2), ' ' )
|
||||||
: std::string();
|
: std::string();
|
||||||
if( colInfo.justification == ColumnInfo::Left )
|
if( colInfo.justification == ColumnInfo::Left )
|
||||||
tp.m_os << " " << colStr << padding << " |";
|
tp.m_os << " " << colStr << padding << " |";
|
||||||
|
@ -112,6 +115,79 @@ namespace {
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Duration {
|
||||||
|
enum class Unit {
|
||||||
|
Auto,
|
||||||
|
Nanoseconds,
|
||||||
|
Microseconds,
|
||||||
|
Milliseconds,
|
||||||
|
Seconds,
|
||||||
|
Minutes
|
||||||
|
};
|
||||||
|
static const uint64_t s_nanosecondsInAMicrosecond = 1000;
|
||||||
|
static const uint64_t s_nanosecondsInAMillisecond = 1000*s_nanosecondsInAMicrosecond;
|
||||||
|
static const uint64_t s_nanosecondsInASecond = 1000*s_nanosecondsInAMillisecond;
|
||||||
|
static const uint64_t s_nanosecondsInAMinute = 60*s_nanosecondsInASecond;
|
||||||
|
|
||||||
|
uint64_t m_inNanoseconds;
|
||||||
|
Unit m_units;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Duration( uint64_t inNanoseconds, Unit units = Unit::Auto )
|
||||||
|
: m_inNanoseconds( inNanoseconds ),
|
||||||
|
m_units( units )
|
||||||
|
{
|
||||||
|
if( m_units == Unit::Auto ) {
|
||||||
|
if( m_inNanoseconds < s_nanosecondsInAMicrosecond )
|
||||||
|
m_units = Unit::Nanoseconds;
|
||||||
|
else if( m_inNanoseconds < s_nanosecondsInAMillisecond )
|
||||||
|
m_units = Unit::Microseconds;
|
||||||
|
else if( m_inNanoseconds < s_nanosecondsInASecond )
|
||||||
|
m_units = Unit::Milliseconds;
|
||||||
|
else if( m_inNanoseconds < s_nanosecondsInAMinute )
|
||||||
|
m_units = Unit::Seconds;
|
||||||
|
else
|
||||||
|
m_units = Unit::Minutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
auto value() const -> double {
|
||||||
|
switch( m_units ) {
|
||||||
|
case Unit::Microseconds:
|
||||||
|
return m_inNanoseconds / static_cast<double>( s_nanosecondsInAMicrosecond );
|
||||||
|
case Unit::Milliseconds:
|
||||||
|
return m_inNanoseconds / static_cast<double>( s_nanosecondsInAMillisecond );
|
||||||
|
case Unit::Seconds:
|
||||||
|
return m_inNanoseconds / static_cast<double>( s_nanosecondsInASecond );
|
||||||
|
case Unit::Minutes:
|
||||||
|
return m_inNanoseconds / static_cast<double>( s_nanosecondsInAMinute );
|
||||||
|
default:
|
||||||
|
return static_cast<double>( m_inNanoseconds );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto unitsAsString() const -> std::string {
|
||||||
|
switch( m_units ) {
|
||||||
|
case Unit::Nanoseconds:
|
||||||
|
return "ns";
|
||||||
|
case Unit::Microseconds:
|
||||||
|
return "µs";
|
||||||
|
case Unit::Milliseconds:
|
||||||
|
return "ms";
|
||||||
|
case Unit::Seconds:
|
||||||
|
return "s";
|
||||||
|
case Unit::Minutes:
|
||||||
|
return "m";
|
||||||
|
default:
|
||||||
|
return "** internal error **";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
friend auto operator << ( std::ostream& os, Duration const& duration ) -> std::ostream& {
|
||||||
|
return os << duration.value() << " " << duration.unitsAsString();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
@ -123,10 +199,10 @@ namespace Catch {
|
||||||
: StreamingReporterBase( config ),
|
: StreamingReporterBase( config ),
|
||||||
m_tablePrinter( config.stream(),
|
m_tablePrinter( config.stream(),
|
||||||
{
|
{
|
||||||
{ "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH-38, ColumnInfo::Left },
|
{ "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH-42, ColumnInfo::Left },
|
||||||
{ "iters", 8, ColumnInfo::Right },
|
{ "iters", 8, ColumnInfo::Right },
|
||||||
{ "elapsed ns", 12, ColumnInfo::Right },
|
{ "elapsed ns", 14, ColumnInfo::Right },
|
||||||
{ "average", 12, ColumnInfo::Right }
|
{ "average", 14, ColumnInfo::Right }
|
||||||
} )
|
} )
|
||||||
{}
|
{}
|
||||||
~ConsoleReporter() override;
|
~ConsoleReporter() override;
|
||||||
|
@ -199,11 +275,11 @@ namespace Catch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void benchmarkEnded( BenchmarkStats const& stats ) override {
|
void benchmarkEnded( BenchmarkStats const& stats ) override {
|
||||||
// !TBD: report average times in natural units?
|
Duration average( stats.elapsedTimeInNanoseconds/stats.iterations );
|
||||||
m_tablePrinter
|
m_tablePrinter
|
||||||
<< stats.iterations << ColumnBreak()
|
<< stats.iterations << ColumnBreak()
|
||||||
<< stats.elapsedTimeInNanoseconds << ColumnBreak()
|
<< stats.elapsedTimeInNanoseconds << ColumnBreak()
|
||||||
<< stats.elapsedTimeInNanoseconds/stats.iterations << " ns" << ColumnBreak();
|
<< average << ColumnBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
void testCaseEnded( TestCaseStats const& _testCaseStats ) override {
|
void testCaseEnded( TestCaseStats const& _testCaseStats ) override {
|
||||||
|
|
Loading…
Reference in New Issue