using namespace std;
using namespace folly;
+// Android doesn't support std::to_string so just use a placeholder there.
+#ifdef __ANDROID__
+#define FOLLY_RANGE_CHECK_TO_STRING(x) std::string("N/A")
+#else
+#define FOLLY_RANGE_CHECK_TO_STRING(x) std::to_string(x)
+#endif
+
+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) {
+ DCHECK_LT(index, sizeof(array) / sizeof(array[0]));
+}
+}
+
////////////////////////////////////////////////////////////////////////////////
// Benchmarks for ASCII to int conversion
////////////////////////////////////////////////////////////////////////////////
void clibAtoiMeasure(unsigned int n, unsigned int digits) {
auto p = pc1.subpiece(pc1.size() - digits, digits);
assert(*p.end() == 0);
- static_assert(sizeof(long) == 8, "64-bit long assumed");
- FOR_EACH_RANGE(i, 0, n) { doNotOptimizeAway(atol(p.begin())); }
-}
-
-void clibStrtoulMeasure(unsigned int n, unsigned int digits) {
- auto p = pc1.subpiece(pc1.size() - digits, digits);
- assert(*p.end() == 0);
- char* endptr;
- FOR_EACH_RANGE(i, 0, n) {
- doNotOptimizeAway(strtoul(p.begin(), &endptr, 10));
- }
+ FOR_EACH_RANGE(i, 0, n) { doNotOptimizeAway(atoll(p.begin())); }
}
void lexicalCastMeasure(unsigned int n, unsigned int digits) {
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));
}
}
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, uint64_t value) {
- FOR_EACH_RANGE(i, 0, n) { to<std::string>(value + n); }
+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());
+ }
+}
+
+// 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());
}
}
}
};
-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.2355f;
+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;
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);
+
+#undef DEFINE_BENCHMARK_GROUP
+
+#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
-#define DEFINE_BENCHMARK_GROUP(n) \
- BENCHMARK_PARAM(u64ToStringClibMeasure, n); \
- BENCHMARK_RELATIVE_PARAM(u64ToStringFollyMeasure, n); \
+#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(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);
+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); \
} // 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}};
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) { \