Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does boost::spirit::hold_any work?

Evidently hold_any has better performance than boost::any. How does it manage to do this?

Edit: Thanks to Mat's comment, I found an answer by hkaiser about hold_any at another question but it lacks details. A more detailed answer would be welcome.

like image 467
amit kumar Avatar asked Nov 10 '12 10:11

amit kumar


2 Answers

I think one of the reasons is because boost::hold_any uses a template metaprogramming approach whilst boost::any uses an inheritance approach.

Internally, boost::spirit::hold_any stores the "value" using a void* and uses another object to keep track of the data type info:

>> boost/spirit/home/support/detail/hold_any.hpp
template <typename Char>
class basic_hold_any
{
    ....
    spirit::detail::fxn_ptr_table<Char>* table;
    void* object;
    ...
}

boost::any stores the "value" using an holder, and it doesn't need another object to keep track of the data type info. The holder is inherited from placeholder and consequently have the inheritance drawbacks.

>> boost/any.hpp
class any
{
    ...
    placeholder * content;
    ...
}


class placeholder
template<typename ValueType>
class holder : public placeholder
{
    ...
    ValueType held;
    ...
}

...the perfomance difference is much more about calling constructors and destructors, but even for casting, boost::spirit::hold_any should be faster.

like image 143
Hugo Corrá Avatar answered Nov 24 '22 07:11

Hugo Corrá


hold_any does two optimization: 1. For small objects it does't allocate memory for object holder but stores it directly in pointer memory; 2. It doesn't use RTTI type comparison (which is slow) but use its own type table

like image 27
AlexT Avatar answered Nov 24 '22 07:11

AlexT