У меня есть необходимость в тестировании производительности для двух решений: одна, которая использует полиморфизм для запуска типа коммутатора и один, который использует случай переключения, чтобы выбрать, какую из функций выполнять. Я  действительно должен оптимизировать этот код. Я написал следующий тестовый пример (вы можете просто скопировать вставку кода, скомпилировать его с помощью g++ -std=c++14 -O3 и запустить его с помощью echo 1 | ./a.out!). Код действительно прост, если вы его прочитали!
#include <iostream>
#include <chrono>
#include <functional>
#include <array>
#include <cassert>
#include <vector>
#include <memory>
using namespace std;
struct profiler
{
    std::string name;
    std::chrono::high_resolution_clock::time_point p;
    profiler(std::string const &n) :
        name(n), p(std::chrono::high_resolution_clock::now()) { }
    ~profiler()
    {
        using dura = std::chrono::duration<double>;
        auto d = std::chrono::high_resolution_clock::now() - p;
        std::cout << name << ": "
            << std::chrono::duration_cast<dura>(d).count()
            << std::endl;
    }
};
#define PROFILE_BLOCK(pbn) profiler _pfinstance(pbn)
class Base {
public:
    virtual int increment(int in) {
        return in + 2;
    }
};
class Derived : public Base {
public:
    int increment(int in) override {
        return ++in;
    }
};
int increment_one(int in) {
    return in + 2;
}
int increment_two(int in) {
    return ++in;
}
int increment_three(int in) {
    return in + 4;
}
int increment_four(int in) {
    return in + 2;
}
static constexpr unsigned long long NUMBER_LOOP{5000000000};
int main() {
    int which_function;
    cin >> which_function;
    {
        PROFILE_BLOCK("nothing");
    }
    {
        PROFILE_BLOCK("switch case");
        auto counter = 0;
        for (unsigned long long i  = 0; i < NUMBER_LOOP; ++i) {
            switch(which_function) {
            case 0:
                counter = increment_one(counter);
                break;
            case 1:
                counter = increment_two(counter);
                break;
            case 2:
                counter = increment_three(counter);
                break;
            case 3:
                counter = increment_four(counter);
                break;
            default:
                assert(false);
                break;
            }
        }
        cout << counter << endl;
    }
    {
        PROFILE_BLOCK("polymorphism");
        auto counter = 0;
        std::unique_ptr<Base> ptr_base{new Derived()};
        for (unsigned long long i = 0; i < NUMBER_LOOP; ++i) {
            counter = ptr_base->increment(counter);
        }
    }
    return 0;
}
Результат, который я получаю, когда я создаю с помощью g++ -std=c++14 -O3 и запускаю с echo 1 | ./a.out,
nothing: 1.167e-06
705032704
switch case: 4.089e-06
polymorphism: 9.299
Я не понимаю, что именно приводит к тому, что коммутационный регистр будет почти таким же быстрым, как и случай nothing. Это из-за inlining? Это потому, что компилятор предварительно вычисляет значения для каждого сценария ввода и помещает их в таблицу поиска? Что заставляет коммутатор так быстро работать?
И как я могу приступить к написанию более справедливого теста производительности для этого сценария? В общем, я никогда не понимаю, быстрый ли код из-за прямого неоптимизированного перевода между кодом С++ и сборкой или же его компилятор предварительно вычисляет значение и полностью пропускает компиляцию и создает код "no-op style".
  Примечание Структура profiler была скопирована непосредственно с другого ответа SO и не имеет отношения к вопросу, кроме того, что он измеряет время
Примечание Как указано в комментариях ниже, @dau_sama работает с тем же тестом в ящике linux с gcc вместо результатов clang в случае коммутатора, занимающего гораздо больше времени (3,34 в этом случае), но все же намного меньше, чем случай полиморфизма.