Created
August 21, 2019 03:39
-
-
Save Cecilwang/5bb06de682d907cfd2c71a4e5f2b782f to your computer and use it in GitHub Desktop.
runtime_poly_bench
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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(); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-std=c++14