Commit 05a4c221 authored by Marcus Holland-Moritz's avatar Marcus Holland-Moritz Committed by Facebook Github Bot 7

Add more benchmarks for integer-to-string conversion

Summary:
In preparation for some changes to the integer-to-string conversion
code, this change adds, this adds some more benchmarks, and attempts
to update the existing ones to be less prone to the optimizations
where the compiler already knows about the constant values being
passed in.

There also were a couple of flaws in the existing benchmarks, where
instead of computing the value to be converted from a start value
and the loop counter, it rather added the (constant) total iteration
count to the value, ending up with a constant. But, worse than just
using a constant, the code that was trying to evaluate the cost of
converting a single-digit would generally end up computing the cost
of a five-digit number, which resulted in the benchmarks showing
identical figures regardless of the number of digits for small digit
counts.

The change also adds benchmarks for positive/negative signed integers
and 128-bit integers.

Reviewed By: yfeldblum

Differential Revision: D3455815

fbshipit-source-id: a20821c7d460bc05453655d0c848a0c9a47520fd
parent 29c7ba51
......@@ -28,6 +28,227 @@
using namespace std;
using namespace folly;
namespace folly {
namespace conv_bench_detail {
// Keep this data global and non-const, so the compiler cannot make
// any assumptions about the actual values at compile time
uint64_t uint64Num[] = {
0,
1ULL,
12ULL,
123ULL,
1234ULL,
12345ULL,
123456ULL,
1234567ULL,
12345678ULL,
123456789ULL,
1234567890ULL,
12345678901ULL,
123456789012ULL,
1234567890123ULL,
12345678901234ULL,
123456789012345ULL,
1234567890123456ULL,
12345678901234567ULL,
123456789012345678ULL,
1234567890123456789ULL,
12345678901234567890ULL,
};
int64_t int64Pos[] = {
0,
1LL,
12LL,
123LL,
1234LL,
12345LL,
123456LL,
1234567LL,
12345678LL,
123456789LL,
1234567890LL,
12345678901LL,
123456789012LL,
1234567890123LL,
12345678901234LL,
123456789012345LL,
1234567890123456LL,
12345678901234567LL,
123456789012345678LL,
1234567890123456789LL,
};
int64_t int64Neg[] = {
0,
-1LL,
-12LL,
-123LL,
-1234LL,
-12345LL,
-123456LL,
-1234567LL,
-12345678LL,
-123456789LL,
-1234567890LL,
-12345678901LL,
-123456789012LL,
-1234567890123LL,
-12345678901234LL,
-123456789012345LL,
-1234567890123456LL,
-12345678901234567LL,
-123456789012345678LL,
-1234567890123456789LL,
};
#if FOLLY_HAVE_INT128_T
unsigned __int128 uint128Num[] = {
0,
static_cast<unsigned __int128>(1) << 0,
static_cast<unsigned __int128>(1) << 4,
static_cast<unsigned __int128>(1) << 7,
static_cast<unsigned __int128>(1) << 10,
static_cast<unsigned __int128>(1) << 14,
static_cast<unsigned __int128>(1) << 17,
static_cast<unsigned __int128>(1) << 20,
static_cast<unsigned __int128>(1) << 24,
static_cast<unsigned __int128>(1) << 27,
static_cast<unsigned __int128>(1) << 30,
static_cast<unsigned __int128>(1) << 34,
static_cast<unsigned __int128>(1) << 37,
static_cast<unsigned __int128>(1) << 40,
static_cast<unsigned __int128>(1) << 44,
static_cast<unsigned __int128>(1) << 47,
static_cast<unsigned __int128>(1) << 50,
static_cast<unsigned __int128>(1) << 54,
static_cast<unsigned __int128>(1) << 57,
static_cast<unsigned __int128>(1) << 60,
static_cast<unsigned __int128>(1) << 64,
static_cast<unsigned __int128>(1) << 67,
static_cast<unsigned __int128>(1) << 70,
static_cast<unsigned __int128>(1) << 74,
static_cast<unsigned __int128>(1) << 77,
static_cast<unsigned __int128>(1) << 80,
static_cast<unsigned __int128>(1) << 84,
static_cast<unsigned __int128>(1) << 87,
static_cast<unsigned __int128>(1) << 90,
static_cast<unsigned __int128>(1) << 94,
static_cast<unsigned __int128>(1) << 97,
static_cast<unsigned __int128>(1) << 100,
static_cast<unsigned __int128>(1) << 103,
static_cast<unsigned __int128>(1) << 107,
static_cast<unsigned __int128>(1) << 110,
static_cast<unsigned __int128>(1) << 113,
static_cast<unsigned __int128>(1) << 117,
static_cast<unsigned __int128>(1) << 120,
static_cast<unsigned __int128>(1) << 123,
static_cast<unsigned __int128>(1) << 127,
};
__int128 int128Pos[] = {
0,
static_cast<__int128>(1) << 0,
static_cast<__int128>(1) << 4,
static_cast<__int128>(1) << 7,
static_cast<__int128>(1) << 10,
static_cast<__int128>(1) << 14,
static_cast<__int128>(1) << 17,
static_cast<__int128>(1) << 20,
static_cast<__int128>(1) << 24,
static_cast<__int128>(1) << 27,
static_cast<__int128>(1) << 30,
static_cast<__int128>(1) << 34,
static_cast<__int128>(1) << 37,
static_cast<__int128>(1) << 40,
static_cast<__int128>(1) << 44,
static_cast<__int128>(1) << 47,
static_cast<__int128>(1) << 50,
static_cast<__int128>(1) << 54,
static_cast<__int128>(1) << 57,
static_cast<__int128>(1) << 60,
static_cast<__int128>(1) << 64,
static_cast<__int128>(1) << 67,
static_cast<__int128>(1) << 70,
static_cast<__int128>(1) << 74,
static_cast<__int128>(1) << 77,
static_cast<__int128>(1) << 80,
static_cast<__int128>(1) << 84,
static_cast<__int128>(1) << 87,
static_cast<__int128>(1) << 90,
static_cast<__int128>(1) << 94,
static_cast<__int128>(1) << 97,
static_cast<__int128>(1) << 100,
static_cast<__int128>(1) << 103,
static_cast<__int128>(1) << 107,
static_cast<__int128>(1) << 110,
static_cast<__int128>(1) << 113,
static_cast<__int128>(1) << 117,
static_cast<__int128>(1) << 120,
static_cast<__int128>(1) << 123,
static_cast<__int128>(3) << 125,
};
__int128 int128Neg[] = {
0,
-(static_cast<__int128>(1) << 0),
-(static_cast<__int128>(1) << 4),
-(static_cast<__int128>(1) << 7),
-(static_cast<__int128>(1) << 10),
-(static_cast<__int128>(1) << 14),
-(static_cast<__int128>(1) << 17),
-(static_cast<__int128>(1) << 20),
-(static_cast<__int128>(1) << 24),
-(static_cast<__int128>(1) << 27),
-(static_cast<__int128>(1) << 30),
-(static_cast<__int128>(1) << 34),
-(static_cast<__int128>(1) << 37),
-(static_cast<__int128>(1) << 40),
-(static_cast<__int128>(1) << 44),
-(static_cast<__int128>(1) << 47),
-(static_cast<__int128>(1) << 50),
-(static_cast<__int128>(1) << 54),
-(static_cast<__int128>(1) << 57),
-(static_cast<__int128>(1) << 60),
-(static_cast<__int128>(1) << 64),
-(static_cast<__int128>(1) << 67),
-(static_cast<__int128>(1) << 70),
-(static_cast<__int128>(1) << 74),
-(static_cast<__int128>(1) << 77),
-(static_cast<__int128>(1) << 80),
-(static_cast<__int128>(1) << 84),
-(static_cast<__int128>(1) << 87),
-(static_cast<__int128>(1) << 90),
-(static_cast<__int128>(1) << 94),
-(static_cast<__int128>(1) << 97),
-(static_cast<__int128>(1) << 100),
-(static_cast<__int128>(1) << 103),
-(static_cast<__int128>(1) << 107),
-(static_cast<__int128>(1) << 110),
-(static_cast<__int128>(1) << 113),
-(static_cast<__int128>(1) << 117),
-(static_cast<__int128>(1) << 120),
-(static_cast<__int128>(1) << 123),
-(static_cast<__int128>(3) << 125),
};
#endif
}
}
using namespace folly::conv_bench_detail;
namespace {
template <typename T>
void checkArrayIndex(const T& array, size_t index) {
assert(index < sizeof(array) / sizeof(array[0]));
}
}
////////////////////////////////////////////////////////////////////////////////
// Benchmarks for ASCII to int conversion
////////////////////////////////////////////////////////////////////////////////
......@@ -145,11 +366,11 @@ unsigned u64ToAsciiTable(uint64_t value, char* dst) {
return length;
}
void u64ToAsciiTableBM(unsigned int n, uint64_t value) {
// This is too fast, need to do 10 times per iteration
void u64ToAsciiTableBM(unsigned int n, size_t index) {
checkArrayIndex(uint64Num, index);
char buf[20];
FOR_EACH_RANGE(i, 0, n) {
doNotOptimizeAway(u64ToAsciiTable(value + n, buf));
doNotOptimizeAway(u64ToAsciiTable(uint64Num[index] + (i % 8), buf));
}
}
......@@ -175,52 +396,77 @@ unsigned u64ToAsciiClassic(uint64_t value, char* dst) {
return length;
}
void u64ToAsciiClassicBM(unsigned int n, uint64_t value) {
// This is too fast, need to do 10 times per iteration
void u64ToAsciiClassicBM(unsigned int n, size_t index) {
checkArrayIndex(uint64Num, index);
char buf[20];
FOR_EACH_RANGE(i, 0, n) {
doNotOptimizeAway(u64ToAsciiClassic(value + n, buf));
doNotOptimizeAway(u64ToAsciiClassic(uint64Num[index] + (i % 8), buf));
}
}
void u64ToAsciiFollyBM(unsigned int n, uint64_t value) {
// This is too fast, need to do 10 times per iteration
void u64ToAsciiFollyBM(unsigned int n, size_t index) {
checkArrayIndex(uint64Num, index);
char buf[20];
FOR_EACH_RANGE(i, 0, n) {
doNotOptimizeAway(uint64ToBufferUnsafe(value + n, buf));
doNotOptimizeAway(uint64ToBufferUnsafe(uint64Num[index] + (i % 8), buf));
}
}
// Benchmark unsigned to string conversion
void u64ToStringClibMeasure(unsigned int n, uint64_t value) {
void u64ToStringClibMeasure(unsigned int n, size_t index) {
// FOLLY_RANGE_CHECK_TO_STRING expands to std::to_string, except on Android
// where std::to_string is not supported
FOR_EACH_RANGE(i, 0, n) { FOLLY_RANGE_CHECK_TO_STRING(value + n); }
checkArrayIndex(uint64Num, index);
FOR_EACH_RANGE (i, 0, n) {
doNotOptimizeAway(
FOLLY_RANGE_CHECK_TO_STRING(uint64Num[index] + (i % 8)).size());
}
}
void u64ToStringFollyMeasure(unsigned int n, size_t index) {
checkArrayIndex(uint64Num, index);
FOR_EACH_RANGE (i, 0, n) {
doNotOptimizeAway(to<std::string>(uint64Num[index] + (i % 8)).size());
}
}
void u64ToStringFollyMeasure(unsigned int n, uint64_t value) {
FOR_EACH_RANGE(i, 0, n) { to<std::string>(value + n); }
// Signed
void i64ToStringFollyMeasurePos(unsigned int n, size_t index) {
checkArrayIndex(int64Pos, index);
FOR_EACH_RANGE (i, 0, n) {
doNotOptimizeAway(to<std::string>(int64Pos[index] + (i % 8)).size());
}
}
void i64ToStringFollyMeasureNeg(unsigned int n, size_t index) {
checkArrayIndex(int64Neg, index);
FOR_EACH_RANGE (i, 0, n) {
doNotOptimizeAway(to<std::string>(int64Neg[index] - (i % 8)).size());
}
}
// Benchmark uitoa with string append
void u2aAppendClassicBM(unsigned int n, uint64_t value) {
void u2aAppendClassicBM(unsigned int n, size_t index) {
checkArrayIndex(uint64Num, index);
string s;
FOR_EACH_RANGE(i, 0, n) {
// auto buf = &s.back() + 1;
char buffer[20];
s.append(buffer, u64ToAsciiClassic(value, buffer));
s.append(buffer, u64ToAsciiClassic(uint64Num[index] + (i % 8), buffer));
doNotOptimizeAway(s.size());
}
}
void u2aAppendFollyBM(unsigned int n, uint64_t value) {
void u2aAppendFollyBM(unsigned int n, size_t index) {
checkArrayIndex(uint64Num, index);
string s;
FOR_EACH_RANGE(i, 0, n) {
// auto buf = &s.back() + 1;
char buffer[20];
s.append(buffer, uint64ToBufferUnsafe(value, buffer));
s.append(buffer, uint64ToBufferUnsafe(uint64Num[index] + (i % 8), buffer));
doNotOptimizeAway(s.size());
}
}
......@@ -251,31 +497,220 @@ struct StringVariadicToBM {
}
};
static size_t bigInt = 11424545345345;
static size_t smallInt = 104;
static char someString[] = "this is some nice string";
static char otherString[] = "this is a long string, so it's not so nice";
static char reallyShort[] = "meh";
static std::string stdString = "std::strings are very nice";
static float fValue = 1.2355;
static double dValue = 345345345.435;
namespace folly {
namespace conv_bench_detail {
// Keep this data global and non-const, so the compiler cannot make
// any assumptions about the actual values at compile time
size_t bigInt = 11424545345345;
size_t smallInt = 104;
char someString[] = "this is some nice string";
char otherString[] = "this is a long string, so it's not so nice";
char reallyShort[] = "meh";
std::string stdString = "std::strings are very nice";
float fValue = 1.2355;
double dValue = 345345345.435;
}
}
BENCHMARK(preallocateTestNoFloat, n) {
for (size_t i = 0; i < n; ++i) {
auto val1 = to<std::string>(bigInt, someString, stdString, otherString);
auto val3 = to<std::string>(reallyShort, smallInt);
auto val2 = to<std::string>(bigInt, stdString);
auto val4 = to<std::string>(bigInt, stdString, dValue, otherString);
auto val5 = to<std::string>(bigInt, someString, reallyShort);
doNotOptimizeAway(
to<std::string>(bigInt, someString, stdString, otherString).size());
doNotOptimizeAway(to<std::string>(reallyShort, smallInt).size());
doNotOptimizeAway(to<std::string>(bigInt, stdString).size());
doNotOptimizeAway(
to<std::string>(bigInt, stdString, dValue, otherString).size());
doNotOptimizeAway(to<std::string>(bigInt, someString, reallyShort).size());
}
}
BENCHMARK(preallocateTestFloat, n) {
for (size_t i = 0; i < n; ++i) {
auto val1 = to<std::string>(stdString, ',', fValue, dValue);
auto val2 = to<std::string>(stdString, ',', dValue);
doNotOptimizeAway(to<std::string>(stdString, ',', fValue, dValue).size());
doNotOptimizeAway(to<std::string>(stdString, ',', dValue).size());
}
}
namespace folly {
namespace conv_bench_detail {
// Keep this data global and non-const, so the compiler cannot make
// any assumptions about the actual values at compile time
int8_t i8s[] = {
-(static_cast<int8_t>(1) << 4),
static_cast<int8_t>(1) << 5,
-(static_cast<int8_t>(1) << 6),
};
uint8_t u8s[] = {
static_cast<uint8_t>(1) << 4,
static_cast<uint8_t>(1) << 5,
static_cast<uint8_t>(1) << 7,
};
int16_t i16s[] = {
-(static_cast<int16_t>(1) << 8),
static_cast<int16_t>(1) << 12,
-(static_cast<int16_t>(1) << 14),
};
uint16_t u16s[] = {
static_cast<uint16_t>(1) << 8,
static_cast<uint16_t>(1) << 12,
static_cast<uint16_t>(1) << 15,
};
int32_t i32s[] = {
-(static_cast<int32_t>(1) << 16),
static_cast<int32_t>(1) << 25,
-(static_cast<int32_t>(1) << 30),
};
uint32_t u32s[] = {
static_cast<uint32_t>(1) << 16,
static_cast<uint32_t>(1) << 25,
static_cast<uint32_t>(1) << 31,
};
int64_t i64s[] = {
-(static_cast<int64_t>(1) << 32),
static_cast<int64_t>(1) << 50,
-(static_cast<int64_t>(1) << 62),
};
uint64_t u64s[] = {
static_cast<uint64_t>(1) << 32,
static_cast<uint64_t>(1) << 50,
static_cast<uint64_t>(1) << 63,
};
}
}
BENCHMARK(preallocateTestInt8, n) {
for (size_t i = 0; i < n; ++i) {
doNotOptimizeAway(to<std::string>(
i8s[0],
',',
u8s[0],
',',
i8s[1],
',',
u8s[1],
',',
i8s[2],
',',
u8s[2])
.size());
}
}
BENCHMARK(preallocateTestInt16, n) {
for (size_t i = 0; i < n; ++i) {
doNotOptimizeAway(to<std::string>(
i16s[0],
',',
u16s[0],
',',
i16s[1],
',',
u16s[1],
',',
i16s[2],
',',
u16s[2])
.size());
}
}
BENCHMARK(preallocateTestInt32, n) {
for (size_t i = 0; i < n; ++i) {
doNotOptimizeAway(to<std::string>(
i32s[0],
',',
u32s[0],
',',
i32s[1],
',',
u32s[1],
',',
i32s[2],
',',
u32s[2])
.size());
}
}
BENCHMARK(preallocateTestInt64, n) {
for (size_t i = 0; i < n; ++i) {
doNotOptimizeAway(to<std::string>(
i64s[0],
',',
u64s[0],
',',
i64s[1],
',',
u64s[1],
',',
i64s[2],
',',
u64s[2])
.size());
}
}
#if FOLLY_HAVE_INT128_T
namespace {
__int128 i128s[] = {
-(static_cast<__int128>(1) << 2),
static_cast<__int128>(1) << 100,
-(static_cast<__int128>(1) << 126),
};
unsigned __int128 u128s[] = {
static_cast<unsigned __int128>(1) << 2,
static_cast<unsigned __int128>(1) << 100,
static_cast<unsigned __int128>(1) << 127,
};
}
BENCHMARK(preallocateTestInt128, n) {
for (size_t i = 0; i < n; ++i) {
doNotOptimizeAway(to<std::string>(
i128s[0],
',',
u128s[0],
',',
i128s[1],
',',
u128s[1],
',',
i128s[2],
',',
u128s[2])
.size());
}
}
BENCHMARK(preallocateTestNoFloatWithInt128, n) {
for (size_t i = 0; i < n; ++i) {
doNotOptimizeAway(
to<std::string>(bigInt, someString, stdString, otherString).size());
doNotOptimizeAway(
to<std::string>(reallyShort, u128s[0], smallInt, i128s[2]).size());
doNotOptimizeAway(
to<std::string>(bigInt, i128s[0], stdString, u128s[1]).size());
doNotOptimizeAway(
to<std::string>(bigInt, stdString, dValue, otherString).size());
doNotOptimizeAway(
to<std::string>(bigInt, u128s[2], someString, reallyShort).size());
}
}
#endif
BENCHMARK_DRAW_LINE();
static const StringIdenticalToBM<std::string> stringIdenticalToBM;
......@@ -290,56 +725,137 @@ static const StringVariadicToBM<fbstring> fbstringVariadicToBM;
BENCHMARK_DRAW_LINE();
DEFINE_BENCHMARK_GROUP(1);
DEFINE_BENCHMARK_GROUP(2);
DEFINE_BENCHMARK_GROUP(3);
DEFINE_BENCHMARK_GROUP(4);
DEFINE_BENCHMARK_GROUP(5);
DEFINE_BENCHMARK_GROUP(6);
DEFINE_BENCHMARK_GROUP(7);
DEFINE_BENCHMARK_GROUP(8);
DEFINE_BENCHMARK_GROUP(9);
DEFINE_BENCHMARK_GROUP(10);
DEFINE_BENCHMARK_GROUP(11);
DEFINE_BENCHMARK_GROUP(12);
DEFINE_BENCHMARK_GROUP(123);
DEFINE_BENCHMARK_GROUP(1234);
DEFINE_BENCHMARK_GROUP(12345);
DEFINE_BENCHMARK_GROUP(123456);
DEFINE_BENCHMARK_GROUP(1234567);
DEFINE_BENCHMARK_GROUP(12345678);
DEFINE_BENCHMARK_GROUP(123456789);
DEFINE_BENCHMARK_GROUP(1234567890);
DEFINE_BENCHMARK_GROUP(12345678901);
DEFINE_BENCHMARK_GROUP(123456789012);
DEFINE_BENCHMARK_GROUP(1234567890123);
DEFINE_BENCHMARK_GROUP(12345678901234);
DEFINE_BENCHMARK_GROUP(123456789012345);
DEFINE_BENCHMARK_GROUP(1234567890123456);
DEFINE_BENCHMARK_GROUP(12345678901234567);
DEFINE_BENCHMARK_GROUP(123456789012345678);
DEFINE_BENCHMARK_GROUP(1234567890123456789);
DEFINE_BENCHMARK_GROUP(12345678901234567890U);
DEFINE_BENCHMARK_GROUP(13);
DEFINE_BENCHMARK_GROUP(14);
DEFINE_BENCHMARK_GROUP(15);
DEFINE_BENCHMARK_GROUP(16);
DEFINE_BENCHMARK_GROUP(17);
DEFINE_BENCHMARK_GROUP(18);
DEFINE_BENCHMARK_GROUP(19);
DEFINE_BENCHMARK_GROUP(20);
#undef DEFINE_BENCHMARK_GROUP
#define DEFINE_BENCHMARK_GROUP(n) \
BENCHMARK_PARAM(u64ToStringClibMeasure, n); \
BENCHMARK_RELATIVE_PARAM(u64ToStringFollyMeasure, n); \
#define DEFINE_BENCHMARK_GROUP(n) \
BENCHMARK_PARAM(u64ToStringClibMeasure, n); \
BENCHMARK_RELATIVE_PARAM(u64ToStringFollyMeasure, n); \
BENCHMARK_RELATIVE_PARAM(i64ToStringFollyMeasurePos, n); \
BENCHMARK_RELATIVE_PARAM(i64ToStringFollyMeasureNeg, n); \
BENCHMARK_DRAW_LINE();
DEFINE_BENCHMARK_GROUP(1);
DEFINE_BENCHMARK_GROUP(2);
DEFINE_BENCHMARK_GROUP(3);
DEFINE_BENCHMARK_GROUP(4);
DEFINE_BENCHMARK_GROUP(5);
DEFINE_BENCHMARK_GROUP(6);
DEFINE_BENCHMARK_GROUP(7);
DEFINE_BENCHMARK_GROUP(8);
DEFINE_BENCHMARK_GROUP(9);
DEFINE_BENCHMARK_GROUP(10);
DEFINE_BENCHMARK_GROUP(11);
DEFINE_BENCHMARK_GROUP(12);
DEFINE_BENCHMARK_GROUP(123);
DEFINE_BENCHMARK_GROUP(1234);
DEFINE_BENCHMARK_GROUP(12345);
DEFINE_BENCHMARK_GROUP(123456);
DEFINE_BENCHMARK_GROUP(1234567);
DEFINE_BENCHMARK_GROUP(12345678);
DEFINE_BENCHMARK_GROUP(123456789);
DEFINE_BENCHMARK_GROUP(1234567890);
DEFINE_BENCHMARK_GROUP(12345678901);
DEFINE_BENCHMARK_GROUP(123456789012);
DEFINE_BENCHMARK_GROUP(1234567890123);
DEFINE_BENCHMARK_GROUP(12345678901234);
DEFINE_BENCHMARK_GROUP(123456789012345);
DEFINE_BENCHMARK_GROUP(1234567890123456);
DEFINE_BENCHMARK_GROUP(12345678901234567);
DEFINE_BENCHMARK_GROUP(123456789012345678);
DEFINE_BENCHMARK_GROUP(1234567890123456789);
DEFINE_BENCHMARK_GROUP(12345678901234567890U);
DEFINE_BENCHMARK_GROUP(13);
DEFINE_BENCHMARK_GROUP(14);
DEFINE_BENCHMARK_GROUP(15);
DEFINE_BENCHMARK_GROUP(16);
DEFINE_BENCHMARK_GROUP(17);
DEFINE_BENCHMARK_GROUP(18);
DEFINE_BENCHMARK_GROUP(19);
// Only for u64
BENCHMARK_PARAM(u64ToStringClibMeasure, 20);
BENCHMARK_RELATIVE_PARAM(u64ToStringFollyMeasure, 20);
BENCHMARK_DRAW_LINE();
#undef DEFINE_BENCHMARK_GROUP
#if FOLLY_HAVE_INT128_T
void u128ToStringFollyMeasure(unsigned int n, size_t index) {
checkArrayIndex(uint128Num, index);
FOR_EACH_RANGE (i, 0, n) {
doNotOptimizeAway(to<std::string>(uint128Num[index] + (i % 8)).size());
}
}
void i128ToStringFollyMeasurePos(unsigned int n, size_t index) {
checkArrayIndex(int128Pos, index);
FOR_EACH_RANGE (i, 0, n) {
doNotOptimizeAway(to<std::string>(int128Pos[index] + (i % 8)).size());
}
}
void i128ToStringFollyMeasureNeg(unsigned int n, size_t index) {
checkArrayIndex(int128Neg, index);
FOR_EACH_RANGE (i, 0, n) {
doNotOptimizeAway(to<std::string>(int128Neg[index] + (i % 8)).size());
}
}
#define DEFINE_BENCHMARK_GROUP(n) \
BENCHMARK_PARAM(u128ToStringFollyMeasure, n); \
BENCHMARK_RELATIVE_PARAM(i128ToStringFollyMeasurePos, n); \
BENCHMARK_RELATIVE_PARAM(i128ToStringFollyMeasureNeg, n); \
BENCHMARK_DRAW_LINE();
DEFINE_BENCHMARK_GROUP(1);
DEFINE_BENCHMARK_GROUP(2);
DEFINE_BENCHMARK_GROUP(3);
DEFINE_BENCHMARK_GROUP(4);
DEFINE_BENCHMARK_GROUP(5);
DEFINE_BENCHMARK_GROUP(6);
DEFINE_BENCHMARK_GROUP(7);
DEFINE_BENCHMARK_GROUP(8);
DEFINE_BENCHMARK_GROUP(9);
DEFINE_BENCHMARK_GROUP(10);
DEFINE_BENCHMARK_GROUP(11);
DEFINE_BENCHMARK_GROUP(12);
DEFINE_BENCHMARK_GROUP(13);
DEFINE_BENCHMARK_GROUP(14);
DEFINE_BENCHMARK_GROUP(15);
DEFINE_BENCHMARK_GROUP(16);
DEFINE_BENCHMARK_GROUP(17);
DEFINE_BENCHMARK_GROUP(18);
DEFINE_BENCHMARK_GROUP(19);
DEFINE_BENCHMARK_GROUP(20);
DEFINE_BENCHMARK_GROUP(21);
DEFINE_BENCHMARK_GROUP(22);
DEFINE_BENCHMARK_GROUP(23);
DEFINE_BENCHMARK_GROUP(24);
DEFINE_BENCHMARK_GROUP(25);
DEFINE_BENCHMARK_GROUP(26);
DEFINE_BENCHMARK_GROUP(27);
DEFINE_BENCHMARK_GROUP(28);
DEFINE_BENCHMARK_GROUP(29);
DEFINE_BENCHMARK_GROUP(30);
DEFINE_BENCHMARK_GROUP(31);
DEFINE_BENCHMARK_GROUP(32);
DEFINE_BENCHMARK_GROUP(33);
DEFINE_BENCHMARK_GROUP(34);
DEFINE_BENCHMARK_GROUP(35);
DEFINE_BENCHMARK_GROUP(36);
DEFINE_BENCHMARK_GROUP(37);
DEFINE_BENCHMARK_GROUP(38);
DEFINE_BENCHMARK_GROUP(39);
BENCHMARK_DRAW_LINE();
#undef DEFINE_BENCHMARK_GROUP
#endif
#define DEFINE_BENCHMARK_GROUP(n) \
BENCHMARK_PARAM(clibAtoiMeasure, n); \
BENCHMARK_RELATIVE_PARAM(lexicalCastMeasure, n); \
......@@ -433,7 +949,11 @@ inline size_t arithToArithClassic(const U* in, uint32_t numItems) {
} // namespace
namespace conv {
namespace folly {
namespace conv_bench_detail {
// Keep this data global and non-const, so the compiler cannot make
// any assumptions about the actual values at compile time
std::array<int, 4> int2ScharGood{{-128, 127, 0, -50}};
std::array<int, 4> int2ScharBad{{-129, 128, 255, 10000}};
......@@ -455,8 +975,7 @@ std::array<double, 4> double2FloatBad{{1e100, 1e101, 1e102, 1e103}};
std::array<double, 4> double2IntGood{{1.0, 10.0, 100.0, 1000.0}};
std::array<double, 4> double2IntBad{{1e100, 1.25, 2.5, 100.00001}};
}
using namespace conv;
}
#define STRING_TO_TYPE_BENCHMARK(type, name, pass, fail) \
BENCHMARK(stringTo##name##Classic, n) { \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment