Boost.Variant 사용과 가상 인터페이스 사용 간의 성능 차이를 측정하려고합니다. 예를 들어 Boost.Variant를 사용하여 여러 유형의 숫자를 균등하게 증가시키고 싶다고 가정 해 봅시다. boost :: variant를 int 및 float에 사용하고 정적 방문자가 각각 하나씩 증가시킵니다. 클래스 인터페이스를 사용하여 순수 가상 클래스 번호와 number_int 및 number_float 클래스를 사용하여이 클래스에서 파생되고 "증분"메소드를 구현합니다.
제 테스트에서 인터페이스를 사용하는 것이 Boost.Variant를 사용하는 것보다 훨씬 빠릅니다. 나는 맨 아래에있는 코드를 실행하고 결과를 받았다 :
가상 : 00 : 00 : 00.001028
변형 : 00 : 00 : 00.012081
Boost.Variant 대 가상 인터페이스 성능
왜이 차이가 생각 하는가? 나는 부스트를 바꿨다. 변이가 훨씬 빨랐다.
** 참고 : 일반적으로 Boost.Variant는 변형이 항상 비어 있지 않음을 보장하기 위해 힙 할당을 사용합니다. 하지만 boost :: has_nothrow_copy가 참이면, 힙 할당을 사용하지 않고 훨씬 빠르게 작업을 수행해야한다는 Boost.Variant 문서를 읽었습니다. int 및 float의 경우 boost :: has_nothrow_copy가 true입니다.
다음은 서로에 대한 두 가지 접근법을 측정하기위한 코드입니다. 나는 약간 좌절 된 후 관심이있는 사람들을 위해
#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;
}
덕분에, 내가 관심! –
결과 및 컴파일러는 무엇입니까? Boost 1.52와 Mingw 4.7을 사용하면 릴리즈 모드에서 약 8 배 더 느리게 변형됩니다. 이상하게도'-O2'는'-O3'보다 약간 빠름/ – AbstractDissonance
g ++ 4.7을 사용하고 Boost 버전은 잘 모르겠지만 아마 1.5x입니다. 나는 컴파일러에 -O2를 전달했으며 결과는 다음과 같습니다. Virtual : 00 : 00 : 00.018806 Variant : 00 : 00 : 00.000001 변형에 00:00:00을 사용하므로 대부분 iterations_count를 10000000으로 설정했습니다. 2.8Ghz Intel Core i7 CPU에서이 테스트를 실행하고 있습니다. –