变体与多态性,与clang和gcc的性能结果截然不同
我试图弄清楚boost::variant的执行时间与多态性方法有多大不同。在我的第一次测试中,我在GCC4.9.1和clang+LLVM3.5上得到了非常不同的结果 您可以在下面找到代码。以下是我的结果: 叮当声+llvm 通用条款: 我用-O3编译了这两个。 有人能解释吗 代码变体与多态性,与clang和gcc的性能结果截然不同,gcc,optimization,boost,clang,c++14,Gcc,Optimization,Boost,Clang,C++14,我试图弄清楚boost::variant的执行时间与多态性方法有多大不同。在我的第一次测试中,我在GCC4.9.1和clang+LLVM3.5上得到了非常不同的结果 您可以在下面找到代码。以下是我的结果: 叮当声+llvm 通用条款: 我用-O3编译了这两个。 有人能解释吗 代码 #包括 #包括 #包括 众所周知,Clang从各种标准库中错误地编译了一些std::vector函数,这是因为它们的内联中存在一些边缘情况。我不知道现在是否已经修好了,但很可能没有。由于unique_ptr比boost
#包括
#包括
#包括
众所周知,Clang从各种标准库中错误地编译了一些std::vector函数,这是因为它们的内联中存在一些边缘情况。我不知道现在是否已经修好了,但很可能没有。由于unique_ptr
比boost::variant
更小、更简单,因此它很可能不会触发这些边缘情况
您发布的代码实际上是“为什么boost::variant
很棒”。一个动态分配和随机指针索引,除了两者都执行的常规间接?这是一个巨大的打击(相对而言)。您运行过多次吗?请发布一些关于“perf stat-r 10”的详细信息,为什么要用“c++14”标记这个问题?您是否使用C++14支持编译过它?我使用OSX,因此无法在pref上发布详细信息,但我多次得到相同的结果。它不使用c++11支持进行编译。我从trunk直接使用llvm+clang得到了相同的结果。我无法在linux/GCC4.9上重新创建您的结果。很难回答硬件/编译器相关的问题。我认为如果粘贴(摘录)生成的汇编代码会更有帮助。
polymorphism: 2.16401
boost::variant: 3.83487
polymorphism: 2.46161
boost::variant: 1.33326
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <ctime>
struct value_type {
value_type() {}
virtual ~value_type() {}
virtual void inc() = 0;
};
struct int_type : value_type {
int_type() : value_type() {}
virtual ~int_type() {}
void inc() { value += 1; }
private:
int value = 0;
};
struct float_type : value_type {
float_type() : value_type() {}
virtual ~float_type() {}
void inc() { value += 1; }
private:
float value = 0;
};
void dyn_test() {
std::vector<std::unique_ptr<value_type>> v;
for (int i = 0; i < 1024; i++) {
if (i % 2 == 0)
v.emplace_back(new int_type());
else
v.emplace_back(new float_type());
}
for (int i = 0; i < 900000; i++) {
std::for_each(v.begin(), v.end(), [](auto &item) { item->inc(); });
}
}
struct visitor : boost::static_visitor<> {
template <typename T> void operator()(T &item) { item += 1; }
};
using mytype = boost::variant<int, float>;
void static_test() {
std::vector<mytype> v;
for (int i = 0; i < 1024; i++) {
if (i % 2 == 0)
v.emplace_back(0);
else
v.emplace_back(0.f);
}
visitor vi;
for (int i = 0; i < 900000; i++) {
std::for_each(v.begin(), v.end(), boost::apply_visitor(vi));
}
}
template <typename F> double measure(F f) {
clock_t start = clock();
f();
clock_t end = clock();
float seconds = (float)(end - start) / CLOCKS_PER_SEC;
return seconds;
}
int main() {
std::cout << "polymorphism: " << measure([] { dyn_test(); }) << std::endl;
std::cout << "boost::variant: " << measure([] { static_test(); }) << std::endl;
return 0;
}