Skip to content

Instantly share code, notes, and snippets.

@fadi-botros
Created September 25, 2021 16:04
Show Gist options
  • Select an option

  • Save fadi-botros/401378c2f648d293a2eb1599e8e6e5be to your computer and use it in GitHub Desktop.

Select an option

Save fadi-botros/401378c2f648d293a2eb1599e8e6e5be to your computer and use it in GitHub Desktop.

Revisions

  1. fadi-botros created this gist Sep 25, 2021.
    77 changes: 77 additions & 0 deletions BenchmarkDependencyInjection.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,77 @@
    #include <memory>

    template<typename Parameter>
    class Consumer {
    public:
    virtual void call(const Parameter &obj) const = 0;
    virtual ~Consumer() {}
    };

    template<typename Callable, typename Parameter>
    class CallableWrapper: public Consumer<Parameter> {
    private:
    Callable callable;
    public:
    CallableWrapper(Callable callable): callable(callable) {}
    virtual void call(const Parameter &obj) const override {
    callable(obj);
    }
    virtual ~CallableWrapper() {}
    };

    template<typename Parameter>
    struct WrapHelper {
    template<typename Callable>
    static auto wrap(Callable callable) {
    return CallableWrapper<Callable, Parameter>(callable);
    }
    };

    class Interface {
    public:
    virtual int method() const = 0;
    virtual ~Interface() {}
    };

    class InterfaceImpl: public Interface {
    public:
    virtual int method() const { return 0; }
    virtual ~InterfaceImpl() {}
    };

    std::unique_ptr<Interface> getAnImpl() {
    return std::make_unique<InterfaceImpl>();
    }

    void injectAnImplViaCallable(const Consumer<Interface> &consumer) {
    // TO PREVENT INLINING
    // DON'T USE IN PRODUCTION
    auto ptr = alloca(4);
    benchmark::DoNotOptimize(ptr);
    // ///////////////////////
    return consumer.call(InterfaceImpl());
    }

    static void ViaReturnAndUniquePtr(benchmark::State& state) {
    // Code inside this loop is measured repeatedly
    for (auto _ : state) {
    auto ptr = getAnImpl();
    int value = ptr->method();
    // Make sure the variable is not optimized away by compiler
    benchmark::DoNotOptimize(value);
    }
    }
    // Register the function as a benchmark
    BENCHMARK(ViaReturnAndUniquePtr);

    static void ViaCallbacks(benchmark::State& state) {
    for (auto _ : state) {
    int value;
    injectAnImplViaCallable(WrapHelper<Interface>::wrap([&](const auto &obj){
    value = obj.method();
    }));
    // Make sure the variable is not optimized away by compiler
    benchmark::DoNotOptimize(value);
    }
    }
    BENCHMARK(ViaCallbacks);