mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-23 03:43:28 +01:00
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 {
|
||||
return m_data->size;
|
||||
}
|
||||
auto String::numberOfCharacters() const noexcept -> size_type {
|
||||
return StringRef( *this ).numberOfCharacters();
|
||||
}
|
||||
auto String::c_str() const noexcept -> char const* {
|
||||
return m_data->chars;
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ namespace Catch {
|
||||
|
||||
auto empty() const noexcept -> bool;
|
||||
auto size() const noexcept -> size_type;
|
||||
auto numberOfCharacters() const noexcept -> size_type;
|
||||
|
||||
auto c_str() const noexcept -> char const*;
|
||||
};
|
||||
|
||||
|
@ -136,7 +136,23 @@ namespace Catch {
|
||||
auto StringRef::size() const noexcept -> size_type {
|
||||
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 {
|
||||
StringBuilder buf;
|
||||
buf.reserve( lhs.size() + rhs.size() );
|
||||
|
@ -56,6 +56,7 @@ namespace Catch {
|
||||
public: // named queries
|
||||
auto empty() const noexcept -> bool;
|
||||
auto size() const noexcept -> size_type;
|
||||
auto numberOfCharacters() const noexcept -> size_type;
|
||||
auto c_str() const -> char const*;
|
||||
|
||||
public: // substrings and searches
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "../internal/catch_console_colour.hpp"
|
||||
#include "../internal/catch_version.h"
|
||||
#include "../internal/catch_text.h"
|
||||
#include "../internal/catch_stringref.h"
|
||||
|
||||
#include <cfloat>
|
||||
#include <cstdio>
|
||||
@ -82,6 +83,8 @@ namespace {
|
||||
|
||||
friend TablePrinter& operator << ( TablePrinter& tp, ColumnBreak ) {
|
||||
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.open();
|
||||
if( tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size()-1) ) {
|
||||
@ -93,8 +96,8 @@ namespace {
|
||||
tp.m_currentColumn++;
|
||||
|
||||
auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
|
||||
auto padding = ( colStr.size()+2 < static_cast<size_t>( colInfo.width ) )
|
||||
? std::string( colInfo.width-(colStr.size()+2), ' ' )
|
||||
auto padding = ( strSize+2 < static_cast<size_t>( colInfo.width ) )
|
||||
? std::string( colInfo.width-(strSize+2), ' ' )
|
||||
: std::string();
|
||||
if( colInfo.justification == ColumnInfo::Left )
|
||||
tp.m_os << " " << colStr << padding << " |";
|
||||
@ -112,6 +115,79 @@ namespace {
|
||||
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 {
|
||||
@ -123,10 +199,10 @@ namespace Catch {
|
||||
: StreamingReporterBase( config ),
|
||||
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 },
|
||||
{ "elapsed ns", 12, ColumnInfo::Right },
|
||||
{ "average", 12, ColumnInfo::Right }
|
||||
{ "elapsed ns", 14, ColumnInfo::Right },
|
||||
{ "average", 14, ColumnInfo::Right }
|
||||
} )
|
||||
{}
|
||||
~ConsoleReporter() override;
|
||||
@ -199,11 +275,11 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
void benchmarkEnded( BenchmarkStats const& stats ) override {
|
||||
// !TBD: report average times in natural units?
|
||||
Duration average( stats.elapsedTimeInNanoseconds/stats.iterations );
|
||||
m_tablePrinter
|
||||
<< stats.iterations << ColumnBreak()
|
||||
<< stats.elapsedTimeInNanoseconds << ColumnBreak()
|
||||
<< stats.elapsedTimeInNanoseconds/stats.iterations << " ns" << ColumnBreak();
|
||||
<< average << ColumnBreak();
|
||||
}
|
||||
|
||||
void testCaseEnded( TestCaseStats const& _testCaseStats ) override {
|
||||
|
Loading…
Reference in New Issue
Block a user