|
@@ -73,12 +73,12 @@ struct AllDiffTypes : EnumValuesAsTuple<AllDiffTypes, DiffType, 4> {
|
|
"ChangeMiddle", "ChangeLast"};
|
|
"ChangeMiddle", "ChangeLast"};
|
|
};
|
|
};
|
|
|
|
|
|
-static constexpr char kSmallStringLiteral[] = "012345678";
|
|
|
|
|
|
+static constexpr char SmallStringLiteral[] = "012345678";
|
|
|
|
|
|
TEST_ALWAYS_INLINE const char* getSmallString(DiffType D) {
|
|
TEST_ALWAYS_INLINE const char* getSmallString(DiffType D) {
|
|
switch (D) {
|
|
switch (D) {
|
|
case DiffType::Control:
|
|
case DiffType::Control:
|
|
- return kSmallStringLiteral;
|
|
|
|
|
|
+ return SmallStringLiteral;
|
|
case DiffType::ChangeFirst:
|
|
case DiffType::ChangeFirst:
|
|
return "-12345678";
|
|
return "-12345678";
|
|
case DiffType::ChangeMiddle:
|
|
case DiffType::ChangeMiddle:
|
|
@@ -88,6 +88,9 @@ TEST_ALWAYS_INLINE const char* getSmallString(DiffType D) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static constexpr char LargeStringLiteral[] =
|
|
|
|
+ "012345678901234567890123456789012345678901234567890123456789012";
|
|
|
|
+
|
|
TEST_ALWAYS_INLINE const char* getLargeString(DiffType D) {
|
|
TEST_ALWAYS_INLINE const char* getLargeString(DiffType D) {
|
|
#define LARGE_STRING_FIRST "123456789012345678901234567890"
|
|
#define LARGE_STRING_FIRST "123456789012345678901234567890"
|
|
#define LARGE_STRING_SECOND "234567890123456789012345678901"
|
|
#define LARGE_STRING_SECOND "234567890123456789012345678901"
|
|
@@ -263,21 +266,26 @@ struct StringRelational {
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
-template <class Rel, class LHLength, class DiffType>
|
|
|
|
|
|
+template <class Rel, class LHLength, class RHLength, class DiffType>
|
|
struct StringRelationalLiteral {
|
|
struct StringRelationalLiteral {
|
|
static void run(benchmark::State& state) {
|
|
static void run(benchmark::State& state) {
|
|
auto Lhs = makeString(LHLength(), DiffType());
|
|
auto Lhs = makeString(LHLength(), DiffType());
|
|
for (auto _ : state) {
|
|
for (auto _ : state) {
|
|
benchmark::DoNotOptimize(Lhs);
|
|
benchmark::DoNotOptimize(Lhs);
|
|
|
|
+ constexpr const char* Literal = RHLength::value == Length::Empty
|
|
|
|
+ ? ""
|
|
|
|
+ : RHLength::value == Length::Small
|
|
|
|
+ ? SmallStringLiteral
|
|
|
|
+ : LargeStringLiteral;
|
|
switch (Rel()) {
|
|
switch (Rel()) {
|
|
case Relation::Eq:
|
|
case Relation::Eq:
|
|
- benchmark::DoNotOptimize(Lhs == kSmallStringLiteral);
|
|
|
|
|
|
+ benchmark::DoNotOptimize(Lhs == Literal);
|
|
break;
|
|
break;
|
|
case Relation::Less:
|
|
case Relation::Less:
|
|
- benchmark::DoNotOptimize(Lhs < kSmallStringLiteral);
|
|
|
|
|
|
+ benchmark::DoNotOptimize(Lhs < Literal);
|
|
break;
|
|
break;
|
|
case Relation::Compare:
|
|
case Relation::Compare:
|
|
- benchmark::DoNotOptimize(Lhs.compare(kSmallStringLiteral));
|
|
|
|
|
|
+ benchmark::DoNotOptimize(Lhs.compare(Literal));
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -285,17 +293,17 @@ struct StringRelationalLiteral {
|
|
|
|
|
|
static bool skip() {
|
|
static bool skip() {
|
|
// Doesn't matter how they differ if they have different size.
|
|
// 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;
|
|
return true;
|
|
// We don't need huge. Doensn't give anything different than Large.
|
|
// 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 true;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
static std::string name() {
|
|
static std::string name() {
|
|
return "BM_StringRelationalLiteral" + Rel::name() + LHLength::name() +
|
|
return "BM_StringRelationalLiteral" + Rel::name() + LHLength::name() +
|
|
- DiffType::name();
|
|
|
|
|
|
+ RHLength::name() + DiffType::name();
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
@@ -393,6 +401,22 @@ void sanityCheckGeneratedStrings() {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 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) {
|
|
int main(int argc, char** argv) {
|
|
benchmark::Initialize(&argc, argv);
|
|
benchmark::Initialize(&argc, argv);
|
|
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
|
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
|
@@ -408,8 +432,16 @@ int main(int argc, char** argv) {
|
|
makeCartesianProductBenchmark<StringRelational, AllRelations, AllLengths,
|
|
makeCartesianProductBenchmark<StringRelational, AllRelations, AllLengths,
|
|
AllLengths, AllDiffTypes>();
|
|
AllLengths, AllDiffTypes>();
|
|
makeCartesianProductBenchmark<StringRelationalLiteral, AllRelations,
|
|
makeCartesianProductBenchmark<StringRelationalLiteral, AllRelations,
|
|
- AllLengths, AllDiffTypes>();
|
|
|
|
|
|
+ AllLengths, AllLengths, AllDiffTypes>();
|
|
makeCartesianProductBenchmark<StringRead, AllTemperatures, AllDepths,
|
|
makeCartesianProductBenchmark<StringRead, AllTemperatures, AllDepths,
|
|
AllLengths>();
|
|
AllLengths>();
|
|
benchmark::RunSpecifiedBenchmarks();
|
|
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);
|
|
|
|
+ }
|
|
}
|
|
}
|