Add tests for Human Readable functionality (#1632)

* Add tests for Human Readable functionality

also fix an issue where the SI/IEC unit wasn't being correctly passed
through.
This commit is contained in:
dominic 2023-07-14 13:56:01 +01:00 committed by GitHub
parent e2556df80f
commit b1c4a752d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 99 additions and 43 deletions

View File

@ -11,6 +11,7 @@
#include <sstream>
#include "arraysize.h"
#include "benchmark/benchmark.h"
namespace benchmark {
namespace {
@ -30,9 +31,8 @@ static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),
static const int64_t kUnitsSize = arraysize(kBigSIUnits);
void ToExponentAndMantissa(double val, double thresh, int precision,
double one_k, std::string* mantissa,
int64_t* exponent) {
void ToExponentAndMantissa(double val, int precision, double one_k,
std::string* mantissa, int64_t* exponent) {
std::stringstream mantissa_stream;
if (val < 0) {
@ -43,8 +43,8 @@ void ToExponentAndMantissa(double val, double thresh, int precision,
// Adjust threshold so that it never excludes things which can't be rendered
// in 'precision' digits.
const double adjusted_threshold =
std::max(thresh, 1.0 / std::pow(10.0, precision));
const double big_threshold = adjusted_threshold * one_k;
std::max(1.0, 1.0 / std::pow(10.0, precision));
const double big_threshold = (adjusted_threshold * one_k) - 1;
const double small_threshold = adjusted_threshold;
// Values in ]simple_threshold,small_threshold[ will be printed as-is
const double simple_threshold = 0.01;
@ -100,29 +100,14 @@ std::string ExponentToPrefix(int64_t exponent, bool iec) {
return std::string(1, array[index]);
}
std::string ToBinaryStringFullySpecified(double value, double threshold,
int precision, double one_k = 1024.0) {
std::string ToBinaryStringFullySpecified(
double value, int precision, Counter::OneK one_k = Counter::kIs1024) {
std::string mantissa;
int64_t exponent;
ToExponentAndMantissa(value, threshold, precision, one_k, &mantissa,
ToExponentAndMantissa(value, precision,
one_k == Counter::kIs1024 ? 1024.0 : 1000.0, &mantissa,
&exponent);
return mantissa + ExponentToPrefix(exponent, false);
}
} // end namespace
void AppendHumanReadable(int n, std::string* str) {
std::stringstream ss;
// Round down to the nearest SI prefix.
ss << ToBinaryStringFullySpecified(n, 1.0, 0);
*str += ss.str();
}
std::string HumanReadableNumber(double n, double one_k) {
// 1.1 means that figures up to 1.1k should be shown with the next unit down;
// this softens edge effects.
// 1 means that we should show one decimal place of precision.
return ToBinaryStringFullySpecified(n, 1.1, 1, one_k);
return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024);
}
std::string StrFormatImp(const char* msg, va_list args) {
@ -155,6 +140,19 @@ std::string StrFormatImp(const char* msg, va_list args) {
return std::string(buff_ptr.get());
}
} // end namespace
void AppendHumanReadable(int n, std::string* str) {
std::stringstream ss;
// Round down to the nearest SI prefix.
ss << ToBinaryStringFullySpecified(n, 0);
*str += ss.str();
}
std::string HumanReadableNumber(double n, Counter::OneK one_k) {
return ToBinaryStringFullySpecified(n, 1, one_k);
}
std::string StrFormat(const char* format, ...) {
va_list args;
va_start(args, format);

View File

@ -6,15 +6,18 @@
#include <utility>
#include <vector>
#include "benchmark/benchmark.h"
#include "benchmark/export.h"
#include "check.h"
#include "internal_macros.h"
namespace benchmark {
BENCHMARK_EXPORT
void AppendHumanReadable(int n, std::string* str);
std::string HumanReadableNumber(double n, double one_k = 1024.0);
BENCHMARK_EXPORT
std::string HumanReadableNumber(double n, Counter::OneK one_k);
BENCHMARK_EXPORT
#if defined(__MINGW32__)

View File

@ -45,7 +45,7 @@ SubMap& GetSubstitutions() {
static SubMap map = {
{"%float", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?"},
// human-readable float
{"%hrfloat", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?[kMGTPEZYmunpfazy]?"},
{"%hrfloat", "[0-9]*[.]?[0-9]+([eE][-+][0-9]+)?[kKMGTPEZYmunpfazy]?i?"},
{"%percentage", percentage_re},
{"%int", "[ ]*[0-9]+"},
{" %s ", "[ ]+"},

View File

@ -6,6 +6,7 @@
#include "../src/internal_macros.h"
#include "../src/string_util.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace {
@ -160,4 +161,58 @@ TEST(StringUtilTest, StrSplit) {
std::vector<std::string>({"hello", "there", "is", "more"}));
}
using AppendHumanReadableFixture =
::testing::TestWithParam<std::tuple<int, std::string>>;
INSTANTIATE_TEST_SUITE_P(
AppendHumanReadableTests, AppendHumanReadableFixture,
::testing::Values(std::make_tuple(0, "0"), std::make_tuple(999, "999"),
std::make_tuple(1000, "1000"),
std::make_tuple(1024, "1Ki"),
std::make_tuple(1000 * 1000, "976\\.56.Ki"),
std::make_tuple(1024 * 1024, "1Mi"),
std::make_tuple(1000 * 1000 * 1000, "953\\.674Mi"),
std::make_tuple(1024 * 1024 * 1024, "1Gi")));
TEST_P(AppendHumanReadableFixture, AppendHumanReadable) {
std::string str;
benchmark::AppendHumanReadable(std::get<0>(GetParam()), &str);
ASSERT_THAT(str, ::testing::MatchesRegex(std::get<1>(GetParam())));
}
using HumanReadableFixture = ::testing::TestWithParam<
std::tuple<double, benchmark::Counter::OneK, std::string>>;
INSTANTIATE_TEST_SUITE_P(
HumanReadableTests, HumanReadableFixture,
::testing::Values(
std::make_tuple(0.0, benchmark::Counter::kIs1024, "0"),
std::make_tuple(999.0, benchmark::Counter::kIs1024, "999"),
std::make_tuple(1000.0, benchmark::Counter::kIs1024, "1000"),
std::make_tuple(1024.0, benchmark::Counter::kIs1024, "1Ki"),
std::make_tuple(1000 * 1000.0, benchmark::Counter::kIs1024,
"976\\.56.Ki"),
std::make_tuple(1024 * 1024.0, benchmark::Counter::kIs1024, "1Mi"),
std::make_tuple(1000 * 1000 * 1000.0, benchmark::Counter::kIs1024,
"953\\.674Mi"),
std::make_tuple(1024 * 1024 * 1024.0, benchmark::Counter::kIs1024,
"1Gi"),
std::make_tuple(0.0, benchmark::Counter::kIs1000, "0"),
std::make_tuple(999.0, benchmark::Counter::kIs1000, "999"),
std::make_tuple(1000.0, benchmark::Counter::kIs1000, "1k"),
std::make_tuple(1024.0, benchmark::Counter::kIs1000, "1.024k"),
std::make_tuple(1000 * 1000.0, benchmark::Counter::kIs1000, "1M"),
std::make_tuple(1024 * 1024.0, benchmark::Counter::kIs1000,
"1\\.04858M"),
std::make_tuple(1000 * 1000 * 1000.0, benchmark::Counter::kIs1000,
"1G"),
std::make_tuple(1024 * 1024 * 1024.0, benchmark::Counter::kIs1000,
"1\\.07374G")));
TEST_P(HumanReadableFixture, HumanReadableNumber) {
std::string str = benchmark::HumanReadableNumber(std::get<0>(GetParam()),
std::get<1>(GetParam()));
ASSERT_THAT(str, ::testing::MatchesRegex(std::get<2>(GetParam())));
}
} // end namespace

View File

@ -16,13 +16,13 @@ void BM_Counters_Thousands(benchmark::State& state) {
{"t0_1000000DefaultBase",
bm::Counter(1000 * 1000, bm::Counter::kDefaults)},
{"t1_1000000Base1000", bm::Counter(1000 * 1000, bm::Counter::kDefaults,
benchmark::Counter::OneK::kIs1000)},
bm::Counter::OneK::kIs1000)},
{"t2_1000000Base1024", bm::Counter(1000 * 1000, bm::Counter::kDefaults,
benchmark::Counter::OneK::kIs1024)},
bm::Counter::OneK::kIs1024)},
{"t3_1048576Base1000", bm::Counter(1024 * 1024, bm::Counter::kDefaults,
benchmark::Counter::OneK::kIs1000)},
bm::Counter::OneK::kIs1000)},
{"t4_1048576Base1024", bm::Counter(1024 * 1024, bm::Counter::kDefaults,
benchmark::Counter::OneK::kIs1024)},
bm::Counter::OneK::kIs1024)},
});
}
BENCHMARK(BM_Counters_Thousands)->Repetitions(2);
@ -30,21 +30,21 @@ ADD_CASES(
TC_ConsoleOut,
{
{"^BM_Counters_Thousands/repeats:2 %console_report "
"t0_1000000DefaultBase=1000k "
"t1_1000000Base1000=1000k t2_1000000Base1024=976.56[23]k "
"t3_1048576Base1000=1048.58k t4_1048576Base1024=1024k$"},
"t0_1000000DefaultBase=1M "
"t1_1000000Base1000=1M t2_1000000Base1024=976.56[23]Ki "
"t3_1048576Base1000=1.04858M t4_1048576Base1024=1Mi$"},
{"^BM_Counters_Thousands/repeats:2 %console_report "
"t0_1000000DefaultBase=1000k "
"t1_1000000Base1000=1000k t2_1000000Base1024=976.56[23]k "
"t3_1048576Base1000=1048.58k t4_1048576Base1024=1024k$"},
"t0_1000000DefaultBase=1M "
"t1_1000000Base1000=1M t2_1000000Base1024=976.56[23]Ki "
"t3_1048576Base1000=1.04858M t4_1048576Base1024=1Mi$"},
{"^BM_Counters_Thousands/repeats:2_mean %console_report "
"t0_1000000DefaultBase=1000k t1_1000000Base1000=1000k "
"t2_1000000Base1024=976.56[23]k t3_1048576Base1000=1048.58k "
"t4_1048576Base1024=1024k$"},
"t0_1000000DefaultBase=1M t1_1000000Base1000=1M "
"t2_1000000Base1024=976.56[23]Ki t3_1048576Base1000=1.04858M "
"t4_1048576Base1024=1Mi$"},
{"^BM_Counters_Thousands/repeats:2_median %console_report "
"t0_1000000DefaultBase=1000k t1_1000000Base1000=1000k "
"t2_1000000Base1024=976.56[23]k t3_1048576Base1000=1048.58k "
"t4_1048576Base1024=1024k$"},
"t0_1000000DefaultBase=1M t1_1000000Base1000=1M "
"t2_1000000Base1024=976.56[23]Ki t3_1048576Base1000=1.04858M "
"t4_1048576Base1024=1Mi$"},
{"^BM_Counters_Thousands/repeats:2_stddev %console_time_only_report [ "
"]*2 t0_1000000DefaultBase=0 t1_1000000Base1000=0 "
"t2_1000000Base1024=0 t3_1048576Base1000=0 t4_1048576Base1024=0$"},