Boost.Variant по сравнению с производительностью виртуального интерфейса

Я пытаюсь измерить разницу в производительности между использованием Boost.Variant и использованием виртуальных интерфейсов. Например, предположим, что я хочу равномерно увеличивать различные типы чисел, используя Boost.Variant, я бы использовал вариант boost ::вместо int и float и статический посетитель, который увеличивает каждое из них. Используя интерфейсы классов, я бы использовал чистый виртуальный класс с номером и номером _int и числом _классов с плавающей запятой, которые являются производными от него и реализуют метод «приращения».

Из моего тестирования использование интерфейсов намного быстрее, чем использование Boost.Variant. Я запустил код внизу и получил следующие результаты:
Виртуальный :00 :00 :00,001028
Вариант :00 :00 :00.012081

Как вы думаете, почему такая разница? Я думал, что Boost.Variant будет намного быстрее.

**Примечание :Обычно Boost.Variant использует выделение кучи, чтобы гарантировать, что вариант всегда будет -непустым.Но я прочитал в документации Boost.Variant, что если boost ::имеет _nothrow _копию верно, то он не использует выделение кучи, что должно значительно ускорить работу. Для int и float boost ::имеет _nothrow _копия истинна.

Вот мой код для сравнения двух подходов друг с другом.

#include <iostream>

#include <boost/variant/variant.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>

#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>

#include <boost/format.hpp>

const int iterations_count = 100000;

// a visitor that increments a variant by N
template <int N>
struct add : boost::static_visitor<> {
    template <typename T>    
    void operator() (T& t) const {
        t += N;
    }
};

// a number interface
struct number {        
    virtual void increment() = 0;
};

// number interface implementation for all types
template <typename T>
struct number_ : number {
    number_(T t = 0) : t(t) {}
    virtual void increment() {
        t += 1;
    }
    T t;
};

void use_virtual() {
    number_<int> num_int;
    number* num = &num_int;

    for (int i = 0; i < iterations_count; i++) {
        num->increment();
    }
}

void use_variant() {
    typedef boost::variant<int, float, double> number;
    number num = 0;

    for (int i = 0; i < iterations_count; i++) {
        boost::apply_visitor(add<1>(), num);
    }
}

int main() {
    using namespace boost::posix_time;

    ptime start, end;
    time_duration d1, d2;

    // virtual
    start = microsec_clock::universal_time();
    use_virtual();
    end = microsec_clock::universal_time();

    // store result
    d1 = end - start;

    // variant
    start = microsec_clock::universal_time();
    use_variant();
    end = microsec_clock::universal_time();

    // store result
    d2 = end - start;

    // output
    std::cout << 
        boost::format(
            "Virtual: %1%\n"
            "Variant: %2%\n"
        ) % d1 % d2;
}
10
задан Tal Zion 10 August 2012 в 17:46
поделиться