"ChangeMiddle", "ChangeLast"};
};
-static constexpr char kSmallStringLiteral[] = "012345678";
+static constexpr char SmallStringLiteral[] = "012345678";
TEST_ALWAYS_INLINE const char* getSmallString(DiffType D) {
switch (D) {
case DiffType::Control:
- return kSmallStringLiteral;
+ return SmallStringLiteral;
case DiffType::ChangeFirst:
return "-12345678";
case DiffType::ChangeMiddle:
}
}
+static constexpr char LargeStringLiteral[] =
+ "012345678901234567890123456789012345678901234567890123456789012";
+
TEST_ALWAYS_INLINE const char* getLargeString(DiffType D) {
#define LARGE_STRING_FIRST "123456789012345678901234567890"
#define LARGE_STRING_SECOND "234567890123456789012345678901"
}
};
-template <class Rel, class LHLength, class DiffType>
+template <class Rel, class LHLength, class RHLength, class DiffType>
struct StringRelationalLiteral {
static void run(benchmark::State& state) {
auto Lhs = makeString(LHLength(), DiffType());
for (auto _ : state) {
benchmark::DoNotOptimize(Lhs);
+ constexpr const char* Literal = RHLength::value == Length::Empty
+ ? ""
+ : RHLength::value == Length::Small
+ ? SmallStringLiteral
+ : LargeStringLiteral;
switch (Rel()) {
case Relation::Eq:
- benchmark::DoNotOptimize(Lhs == kSmallStringLiteral);
+ benchmark::DoNotOptimize(Lhs == Literal);
break;
case Relation::Less:
- benchmark::DoNotOptimize(Lhs < kSmallStringLiteral);
+ benchmark::DoNotOptimize(Lhs < Literal);
break;
case Relation::Compare:
- benchmark::DoNotOptimize(Lhs.compare(kSmallStringLiteral));
+ benchmark::DoNotOptimize(Lhs.compare(Literal));
break;
}
}
static bool skip() {
// Doesn't matter how they differ if they have different size.
- if (LHLength() != Length::Small && DiffType() != ::DiffType::Control)
+ if (LHLength() != RHLength() && DiffType() != ::DiffType::Control)
return true;
// We don't need huge. Doensn't give anything different than Large.
- if (LHLength() == Length::Huge)
+ if (LHLength() == Length::Huge || RHLength() == Length::Huge)
return true;
return false;
}
static std::string name() {
return "BM_StringRelationalLiteral" + Rel::name() + LHLength::name() +
- DiffType::name();
+ RHLength::name() + DiffType::name();
}
};
}
}
+// Some small codegen thunks to easily see generated code.
+bool StringEqString(const std::string& a, const std::string& b) {
+ return a == b;
+}
+bool StringEqCStr(const std::string& a, const char* b) { return a == b; }
+bool CStrEqString(const char* a, const std::string& b) { return a == b; }
+bool StringEqCStrLiteralEmpty(const std::string& a) {
+ return a == "";
+}
+bool StringEqCStrLiteralSmall(const std::string& a) {
+ return a == SmallStringLiteral;
+}
+bool StringEqCStrLiteralLarge(const std::string& a) {
+ return a == LargeStringLiteral;
+}
+
int main(int argc, char** argv) {
benchmark::Initialize(&argc, argv);
if (benchmark::ReportUnrecognizedArguments(argc, argv))
makeCartesianProductBenchmark<StringRelational, AllRelations, AllLengths,
AllLengths, AllDiffTypes>();
makeCartesianProductBenchmark<StringRelationalLiteral, AllRelations,
- AllLengths, AllDiffTypes>();
+ AllLengths, AllLengths, AllDiffTypes>();
makeCartesianProductBenchmark<StringRead, AllTemperatures, AllDepths,
AllLengths>();
benchmark::RunSpecifiedBenchmarks();
+
+ if (argc < 0) {
+ // ODR-use the functions to force them being generated in the binary.
+ auto functions = std::make_tuple(
+ StringEqString, StringEqCStr, CStrEqString, StringEqCStrLiteralEmpty,
+ StringEqCStrLiteralSmall, StringEqCStrLiteralLarge);
+ printf("%p", &functions);
+ }
}