我想知道在任何可以使用模板的情况下使用boost.any(无RTTI)类是否会降低程序的速度。由于boost any实际上是模板类的包装器,可以说现代编译器优化它会产生相同的效果,我是对的吗?
#include <iostream>
#include <vector>
using namespace std;
template<class T> class tpl
{
T content;
public:
tpl(const T& value) : content(value) {}
operator T() const
{
return content;
}
};
class any
{
public:
any() : content(0) {}
any(const any& other) : content(other.content -> clone()) {}
template<class T> any(const T& value) : content(new holder<T>(value))
{
}
~any()
{
delete content;
}
class placeholder
{
public:
placeholder() {}
virtual placeholder* clone() const = 0;
};
template<class T> class holder : public placeholder
{
public:
T content;
holder(const T& value) : content(value) {}
~holder() {}
placeholder* clone() const
{
return new holder<T>(content);
}
};
template<class T> operator T () const
{
return dynamic_cast<holder<T>*>(content)->content;
}
placeholder* content;
};
template<class T> void test()
{
for (int i = 0; i < 10000; ++i)
{
vector<T> a;
a.push_back(23.23);
a.push_back(3.14);
double x = (double)a[0];
}
}
这样说是正确的:
test<any>();
和以下一样快:
test<tpl<double>>();
假设您知道,就像编译器在第二个示例中所做的那样,boost::any
在这种情况下仅用作double? (任何课程都没有RTTI。)
我更想知道支持和反对这一论点的论据。
此外,是否存在这些方法之间存在差异的具体情况?
修改 性能测试2:
似乎存在相对较大的差异。
编辑2:
由于将主要数据类型double
与类any
进行比较是不公平的,因此我进行了新的测试:
#include "tpl_vs_any.hpp"
int main()
{
test<any>();
return 0;
}
速度:1,794.54毫秒
#include "tpl_vs_any.hpp"
int main()
{
test<tpl<double>>();
return 0;
}
速度:1,715.57毫秒
多次测试,几乎相同的基准测试。
答案 0 :(得分:2)
这样说是正确的:
...
和以下一样快:
...
假设您知道,就像编译器在第二个示例中所做的那样,在这种情况下,boost :: any仅用作double?
没有。目前的编译器远没有那种内省程度。 boost::any
会慢一些。
当然,您可以运行代码并自行查找。
答案 1 :(得分:2)
boost::any
在内部保存一个指向对象的指针,该对象使用new
分配。使std::vector
显着快于std::list
的事情之一就是向量将所有对象保存在单个分配中的连续存储中,除了显着减少内存分配开销之外,也更加缓存友好。
还有将RTTI添加到分配的细节,这通常是微不足道的开销,但在像double
这样的非常小的类型的情况下,显着增加了存储开销。
boost::any
不是标准的一部分;它是特定模板的特定实现。所以你不妨只是对它进行基准测试;没有一堆其他竞争的“标准实施”。