I was wondering if using boost.any (Without RTTI) classes anywhere templates can be used will slow down the program. Since boost any is actually a wrapper around a template class, one could say that with the modern compiler-optimalisations it will produce the same effect, am I right?
#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];
}
}
So would it be correct to say that:
test<any>();
Is exactly as fast as:
test<tpl<double>>();
Assuming that you know, just like the compiler does at the second example, that boost::any
is only used as double in this situation? (No RTTI for the any class).
I'm more wondering about the arguments for and against this thesis.
Also, are there specific situations where there is difference between those methods?
Edit: Performance test 2:
It seems like there is a relativly large difference.
Edit 2:
Since it was not fair to compare the primary data type double
against the class any
I've made a new test:
#include "tpl_vs_any.hpp"
int main()
{
test<any>();
return 0;
}
Speed: 1,794.54 ms
#include "tpl_vs_any.hpp"
int main()
{
test<tpl<double>>();
return 0;
}
Speed: 1,715.57 ms
Tested it multiple times, pretty much the same benchmarks.
So would it be correct to say that:
...
Is exactly as fast as:
...
Assuming that you know, just like the compiler does at the second example, that boost::any is only used as double in this situation?
No. Current compilers do nowhere near that kind of level of introspection. boost::any
will be slower.
Of course, you could just run the code and find out for yourself.
boost::any
internally holds a pointer to an object, which it allocates with new
. One of the things that makes std::vector
significantly faster than, say, std::list
is that vector keeps all of its objects in a contiguous storage in a single allocation, which aside from the obvious reduction in memory allocation overhead, is also a lot more cache-friendly.
There's also the detail of adding RTTI to the allocation, which is generally trivial overhead, but in the case of really small types like double
significantly increases the storage overhead.
boost::any
is not part of the standard; it's a specific implementation of a specific template. So you might as well just benchmark it; there aren't a bunch of other competing "standard implementations".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With