我试图衡量使用Boost.Variant和使用虚拟接口之间的性能差异。例如,假设我想要使用Boost.Variant来统一增加不同类型的数字,我会在int和float上使用boost :: variant,并使用静态访问器来增加它们中的每一个。使用类接口我会使用一个纯虚拟类号和number_int和number_float类,它们派生自它并实现“增量”方法。
从我的测试中,使用接口比使用Boost.Variant快得多。 我跑在底部的代码,并获得这些结果:
虚拟:00:00:00.001028
变:00:00:00.012081
Boost.Variant与虚拟接口性能
,你为什么认为这种差异是什么?我认为Boost.Variant会更快。
**注意:通常Boost.Variant使用堆分配来保证变体总是非空的。但是我阅读了Boost.Variant文档,如果boost :: has_nothrow_copy是真的,那么它不会使用堆分配,这会使事情显着加快。对于int和float boost :: has_nothrow_copy是真的。
这是我的代码,用于测量两种方法相互对抗。
#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;
}
感谢张贴的后续,我很感兴趣! – 2012-10-30 04:00:29
你的结果和编译器是什么?使用Boost 1.52和Mingw 4.7,我发现变体在释放模式下慢了大约8倍。奇怪的是'-O2'比'-O3'略快;/ – AbstractDissonance 2012-11-25 12:15:18
我使用的是g ++ 4.7,我不知道是什么Boost版本,但它可能是1.5x。我将-O2传递给编译器,结果如下: 虚拟:00:00:00.018806 变体:00:00:00.000001 大多数情况下,我会在变体上获取00:00:00,因此我将iterations_count设置为1000000 我在2.8Ghz Intel Core i7 CPU上运行这个测试。 – 2012-11-26 12:25:37