Skip to content

Instantly share code, notes, and snippets.

@n0phx
Created May 16, 2018 20:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n0phx/9c6748c653312ef933c4c8eb770bd285 to your computer and use it in GitHub Desktop.
Save n0phx/9c6748c653312ef933c4c8eb770bd285 to your computer and use it in GitHub Desktop.
#include <benchmark/benchmark.h>
#include <unordered_map>
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const
{
return static_cast<std::size_t>(t);
}
};
struct not_found
{
};
template <typename TKey, typename TValue, TKey...>
struct JumpTable;
template <typename TKey, typename TValue>
struct JumpTable<TKey, TValue>
{
TValue& operator[]([[maybe_unused]] TKey needed)
{
throw not_found{};
}
};
template <typename TKey, typename TValue, TKey key, TKey... rest>
struct JumpTable<TKey, TValue, key, rest...> : JumpTable<TKey, TValue, rest...>
{
TValue value;
using super = JumpTable<TKey, TValue, rest...>;
TValue& operator[](TKey k)
{
return key == k ? value : super::operator[](k);
}
};
enum class DispatchId
{
Id1 = 10,
Id2 = 20,
Id3 = 30
};
using FuncType = int (*)(int);
class Dispatcher
{
private:
FuncType m_fn1;
FuncType m_fn2;
FuncType m_fn3;
public:
FuncType& find(DispatchId id)
{
switch (id)
{
case DispatchId::Id1:
return m_fn1;
case DispatchId::Id2:
return m_fn2;
case DispatchId::Id3:
return m_fn3;
default:
throw not_found{};
}
}
};
int fn1(int x)
{
return x + 1;
}
int fn2(int x)
{
return x + 2;
}
int fn3(int x)
{
return x + 3;
}
static void UnorderedMapDispatch(benchmark::State& state)
{
std::unordered_map<DispatchId, FuncType, EnumClassHash> dm;
dm.insert({DispatchId::Id1, fn1});
dm.insert({DispatchId::Id2, fn2});
dm.insert({DispatchId::Id3, fn3});
for (auto _ : state)
{
dm.at(static_cast<DispatchId>(state.range(0)))(state.range(0));
}
}
BENCHMARK(UnorderedMapDispatch)->Arg(10)->Arg(20)->Arg(30);
static void SwitchDispatch(benchmark::State& state)
{
Dispatcher d;
d.find(DispatchId::Id1) = fn1;
d.find(DispatchId::Id2) = fn2;
d.find(DispatchId::Id3) = fn3;
for (auto _ : state)
{
d.find(static_cast<DispatchId>(state.range(0)))(state.range(0));
}
}
BENCHMARK(SwitchDispatch)->Arg(10)->Arg(20)->Arg(30);
static void JumpTableDispatch(benchmark::State& state)
{
JumpTable<DispatchId, FuncType, DispatchId::Id1, DispatchId::Id2, DispatchId::Id3> jt;
jt[DispatchId::Id1] = fn1;
jt[DispatchId::Id2] = fn2;
jt[DispatchId::Id3] = fn3;
for (auto _ : state)
{
jt[static_cast<DispatchId>(state.range(0))](state.range(0));
}
}
BENCHMARK(JumpTableDispatch)->Arg(10)->Arg(20)->Arg(30);
BENCHMARK_MAIN();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment