问题
To hold arbitrarily large objects, boost::any
/ std::any
surely needs to allocate heap space for objects. However, for small types whose size is less or equal to a pointer (int,char,bool,...
), any
could instead store the value in-place in the pointer slot or in some other in-place memory and not allocate heap space. But does the implementation do this?
I have a scenario where I often store small types in an any
and only sometimes larger types like string
s. The code is quite hot and therefore I am asking the question. If the optimization is not performed, I might be better off with an own implementation that stores small types in-place.
回答1:
There is no guarantee but the C++17 draft states in [any.class] that
Implementations should avoid the use of dynamically allocated memory for a small contained object. [ Example: where the object constructed is holding only an int. — end example ] Such small-object optimization shall only be applied to types
T
for whichis_nothrow_move_constructible_v<T>
istrue
.
Unfortunately it does not give a recommendation for what should be considered small except to say a int
should be able to be stored in place.
回答2:
If I understand the Boost.Any source code correctly, and from poking at it in a debugger, it does not apply a small object optimization. (Note the unconditional use of new.)
template<typename ValueType>
any(const ValueType & value)
: content(new holder<
BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
>(value))
{
}
回答3:
Nathan Oliver's and Josh's Kelley's answers are correct: There is no guarantee, boost does not use the small value optimization.
In more practical cases, https://github.com/llvm-mirror/libcxx/blob/master/include/experimental/any#L129 Shows you libc++ (clang's) gives you 3 void pointers worth of space, (24 bytes if they are 8 bytes wide)
libstdc++ only one pointer: https://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/include/experimental/any?view=markup#l106
Changing any
to make the size a template parameter is not difficult, just that you should also make sure there is convertibility between any
of different sizes.
IMO, the performance difference is so substantial between small size optimization and heap allocated, according to my benchmarks, and the implementation cost of making it a template so small it will become part of the standard
来源:https://stackoverflow.com/questions/41878040/does-boostany-stdany-store-small-objects-in-place