Skip to content

Commit

Permalink
When ranking overloaded callables, break when an exactly matched call…
Browse files Browse the repository at this point in the history
…able is found to improve performance
  • Loading branch information
wqking committed Jul 19, 2024
1 parent dbdbfb3 commit 2ef2ea1
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 9 deletions.
13 changes: 7 additions & 6 deletions include/metapp/implement/internal/declareutil_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,10 @@
#include <type_traits>
#include <numeric>
#include <algorithm>
#include <limits>

namespace metapp {

static constexpr int invokeRankMatch = 1000;
static constexpr int invokeRankCast = 1;
static constexpr int invokeRankNone = 0;

namespace internal_ {

template <typename TL, std::size_t N>
Expand Down Expand Up @@ -88,7 +85,7 @@ struct MetaCallableInvokeChecker
template <int ...Indexes>
static int doRankInvoke(const ArgumentSpan & arguments, IntConstantList<Indexes...>) {
if(argCount == arguments.size() && arguments.empty()) {
return invokeRankMatch;
return invokeRankMax;
}
std::array<int, argCount> rankList {
rankArgumentMatching<ArgumentTypeList, Indexes>(arguments)...
Expand All @@ -97,13 +94,17 @@ struct MetaCallableInvokeChecker
(void)arguments;
(void)rankList;
int rank = 0;
bool allMatchExactly = true;
for(auto it = std::begin(rankList); it != std::end(rankList); ++it) {
if(*it == invokeRankNone) {
return invokeRankNone;
}
if(*it != invokeRankMatch) {
allMatchExactly = false;
}
rank += *it;
}
return rank;
return allMatchExactly ? invokeRankMax : rank;
}
};

Expand Down
8 changes: 8 additions & 0 deletions include/metapp/interfaces/metacallable.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ class MetaCallable
}
};

static constexpr int invokeRankMatch = 1000;
static constexpr int invokeRankCast = 1;
static constexpr int invokeRankNone = 0;
static constexpr int invokeRankMax = std::numeric_limits<int>::max();

template <typename Iterator>
Iterator findCallable(
Iterator first,
Expand All @@ -133,6 +138,9 @@ Iterator findCallable(
if(rank > maxRank) {
maxRank = rank;
result = first;
if(rank == invokeRankMax) {
break;
}
}
}

Expand Down
22 changes: 22 additions & 0 deletions tests/benchmark/benchmark_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,27 @@ BenchmarkFunc
printResult(t2, iterations, "Misc, Fill std::vector<metapp::Variant>, MetaIndexable");
}

metapp::Variant tempGet(const int n)
{
switch(n) {
case 0:
return 5LL;
case 1:
return 6LL;
}
return "abc";
}

TEST_CASE("temp")
{
constexpr int iterations = generalIterations;
const auto t1 = measureElapsedTime([iterations]() {
for(int i = 0; i < iterations; ++i) {
metapp::Variant v = tempGet(i % 2);
dontOptimizeAway(v);
}
});
printResult(t1, iterations, "Misc, temp");
}

} //namespace
2 changes: 1 addition & 1 deletion tests/unittest/metatypes/test_default_args_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ TEST_CASE("metatypes, DefaultArgsFunction, MyClass::myFunc2")
REQUIRE(metapp::callableRankInvoke(v, &obj, 5) == metapp::invokeRankNone);
// metapp::invokeRankMatch * 3 is each of the three default arguments receives metapp::invokeRankMatch.
REQUIRE(metapp::callableRankInvoke(v, &obj, 5, std::string("abc"))
== metapp::invokeRankMatch + metapp::invokeRankMatch + metapp::invokeRankMatch * 3);
== metapp::invokeRankMax);
REQUIRE(metapp::callableRankInvoke(v, &obj, 5, "abc")
== metapp::invokeRankMatch + metapp::invokeRankCast + metapp::invokeRankMatch * 3);
REQUIRE(metapp::callableRankInvoke(v, &obj, 5, "abc", 6)
Expand Down
4 changes: 2 additions & 2 deletions tests/unittest/test_metacallable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ namespace {

TEST_CASE("MetaCallable, rankInvoke")
{
REQUIRE(metapp::callableRankInvoke(std::function<void (int)>(), nullptr, 5) == metapp::invokeRankMatch);
REQUIRE(metapp::callableRankInvoke(std::function<void (int)>(), nullptr, 5) == metapp::invokeRankMax);
REQUIRE(metapp::callableRankInvoke(std::function<void (int)>(), nullptr, metapp::Variant(5)) == metapp::invokeRankCast);

REQUIRE(metapp::callableRankInvoke(std::function<void (std::string)>(), nullptr, std::string("abc")) == metapp::invokeRankMatch);
REQUIRE(metapp::callableRankInvoke(std::function<void (std::string)>(), nullptr, std::string("abc")) == metapp::invokeRankMax);
REQUIRE(metapp::callableRankInvoke(std::function<void (std::string)>(), nullptr, "abc") == metapp::invokeRankCast);

REQUIRE(metapp::callableRankInvoke(std::function<void (long, std::string)>(), nullptr, 5, "abc") == metapp::invokeRankCast + metapp::invokeRankCast);
Expand Down

1 comment on commit 2ef2ea1

@eliasdiek
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wqking hey ,I'm looking for someone with your stack to work on our platform ,either as a freelancer or in a full time role . are you up for it ? contact me on telegram @eliasdiek or via email at [email protected]

Please sign in to comment.