Skip to content

Instantly share code, notes, and snippets.

@Cecilwang
Created August 21, 2019 03:39
Show Gist options
  • Select an option

  • Save Cecilwang/5bb06de682d907cfd2c71a4e5f2b782f to your computer and use it in GitHub Desktop.

Select an option

Save Cecilwang/5bb06de682d907cfd2c71a4e5f2b782f to your computer and use it in GitHub Desktop.
runtime_poly_bench
#include <memory>
#include "benchmark/benchmark.h"
struct A {
int f1() { return ++v; }
int f2() { return ++v; }
int v;
};
struct NoVirtual : public A {};
struct Base {
virtual int f1() { return ++v; }
virtual int f2() { return ++v; }
int v;
};
struct Derived : public Base {
int f1() override { return ++v; }
int f2() override { return ++v; }
};
struct Derived1 : public Derived {
int f1() override { return ++v; }
int f2() override { return ++v; }
};
struct PureBase {
virtual int f1() = 0;
virtual int f2() = 0;
int v;
};
struct PureDerived : public PureBase {
int f1() override { return ++v; }
int f2() override { return ++v; }
};
template <typename T>
void Bench(benchmark::State& state) { // NOLINT
T t1;
T t2;
for (auto _ : state) {
for (int i = 0; i < 100; ++i) {
benchmark::DoNotOptimize(t1);
t1.f1();
benchmark::DoNotOptimize(t1);
t1.f2();
benchmark::DoNotOptimize(t2);
t2.f1();
benchmark::DoNotOptimize(t2);
t2.f2();
}
}
}
BENCHMARK_TEMPLATE(Bench, A);
BENCHMARK_TEMPLATE(Bench, NoVirtual);
BENCHMARK_TEMPLATE(Bench, Base);
BENCHMARK_TEMPLATE(Bench, Derived);
BENCHMARK_TEMPLATE(Bench, Derived1);
BENCHMARK_TEMPLATE(Bench, PureDerived);
struct Sean {
public:
template <typename T>
explicit Sean(T x) : self_(std::make_unique<Model<T>>(std::move(x))) {}
int f1() { return self_->f1(); }
int f2() { return self_->f2(); }
[39/442]
private:
struct Concept {
virtual ~Concept() = default;
virtual int f1() = 0;
virtual int f2() = 0;
};
template <typename T>
struct Model final : Concept {
explicit Model(T x) : data_(std::move(x)) {}
int f1() override { return data_.f1(); }
int f2() override { return data_.f2(); }
A data_;
};
std::unique_ptr<Concept> self_;
};
void BenchSean(benchmark::State& state) { // NOLINT
A a1;
Sean t1(a1);
A a2;
Sean t2(a2);
for (auto _ : state) {
for (int i = 0; i < 100; ++i) {
// benchmark::DoNotOptimize(t1);
// benchmark::DoNotOptimize(t2);
t1.f1();
t1.f2();
t2.f1();
t2.f2();
}
}
}
BENCHMARK(BenchSean);
struct VTable {
int (*f1)(void* p_);
int (*f2)(void* p_);
};
template <typename T>
VTable const VTableFor = {[](void* p_) { return static_cast<T*>(p_)->f1(); },
[](void* p_) { return static_cast<T*>(p_)->f2(); }};
class Dyno {
VTable const vtbl_;
std::aligned_storage<64> buffer_;
public:
template <typename T>
Dyno(T x) : vtbl_{VTableFor<T>} {
new (&buffer_) T(x);
}
int f1() { return vtbl_.f1(&buffer_); }
int f2() { return vtbl_.f2(&buffer_); }
};
void BenchDyno(benchmark::State& state) { // NOLINT
A a;
Dyno t1(a);
Dyno t2(a);
for (auto _ : state) {
for (int i = 0; i < 100; ++i) {
t1.f1();
t1.f2();
t2.f1();
t2.f2();
}
}
}
BENCHMARK(BenchDyno);
BENCHMARK_MAIN();
@Cecilwang
Copy link
Author

-std=c++14

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment