Который работает быстрее? поиск в vtable с N производными типами или поиск в std :: map с N элементами?

0
#include <iostream>
#include <map>
#include <ctime>

struct Base { virtual void foo() {} };
struct A : Base { void foo() {} };
struct B : Base { void foo() {} };
struct C : Base { void foo() {} };

A* protoA = new A;  B* protoB = new B;  C* protoC = new C;

enum Tag {a, b, c};

std::map<Tag, Base*> protoMap = { {a, protoA}, {b, protoB}, {c, protoC} };

void goo(Base* base) {base->foo();}

void hoo(Tag tag) {protoMap[tag]->foo();}

struct Timer {
    const std::clock_t begin;
    Timer() : begin (std::clock()) {}
    ~Timer() {
        const std::clock_t end = std::clock();
        std::cout << double (end - begin) / CLOCKS_PER_SEC << " seconds." << std::endl;
    };
};

int main() {
    const long N = 10000000;
    {
        Timer timer;
        for (int i = 0; i < N; i++)
            goo(new C);  // using vtable
    }  // 0.445 seconds.
    {
        Timer timer;
        for (int i = 0; i < N; i++)
            hoo(c);  // using map
    }  // 0.605 seconds.
    std::cin.get();
}

Но мой тест использует только три производных класса, и я не знаю, как определить тысячи производных классов для правильной оценки. Кто-нибудь знает ответ уже, так что мне не нужно думать о том, как проводить лучшие тесты?

Я в ситуации, когда я могу легко использовать карту, но для повышения производительности с помощью vtable look-up потребуется перепроектировать много вещей, которые у меня уже есть (добавьте новый элемент данных в класс, определите новый конструктор, реализовать шаблон посетителя и т.д.).

  • 0
    Вы сравниваете яблоки с апельсинами; Как этот подход «тега» помогает в реалистичном полиморфном сценарии?
  • 0
    @Оливер. Потому что я нахожусь в ситуации, когда я могу легко использовать карту, но попытка улучшить производительность с помощью поиска в vtable потребует перестройки многих вещей, которые у меня уже есть (добавление нового члена данных в класс, определение нового конструктор, реализация шаблона посетителя и т. д.).
Показать ещё 4 комментария
Теги:
performance
vtable
map

1 ответ

0
Лучший ответ

Без сомнения, самый быстрый способ - это vtable.

Экспериментирование:

Вы должны запустить свой тест в аналогичных условиях. Нецелесообразно выделять новый элемент для каждого вызова для теста vtable, но не выделять ничего в подход карты.

Я проверил тест, используя подход vtable, используя указатель на уже выделенный элемент. Я получил 16 мс для vtable и 78 мс для подхода карты.

Если вы хотите пойти дальше и ралли сравнить 1000-й производные, вам придется работать с рекурсивным шаблоном.

Объяснение результата:

Обычно просмотр vtable использует фиксированное смещение в vtable объекта, а не поиск. Таким образом, даже с 1000 выводами вы будете иметь постоянное время реакции в O (1).

Карта должна будет выполнить дорогостоящую операцию поиска на клавише, то есть O (log (n)).

Дополнительные замечания:

Реализация карты, которую вы предлагаете, не будет работать в reallife, потому что вы всегда вызываете функцию-член для ONE SINGLE предопределенного объекта: тот, который вы сохранили на карте. Виртуальная функция будет работать с любым объектом семейства.

  • 0
    Да, спасибо. Я провел свой тест, используя шаблон для создания множества классов. vtable, безусловно, выигрывает, и его время не меняется в зависимости от количества производных классов.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню