Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-11-16 07:27:32


"Jaap Suter" <boost_at_[hidden]> writes:

> Hello,
>
> can any compiler expert give me feedback on whether there should be a
> noticable difference in compilation speed between the following two
> meta-functions:
>
> template<class N, class M, class Q, class P>
> struct foo : mpl::plus
> <
> N,
> typename mpl::minus
> <
> M,
> typename mpl::divides
> <
> Q,
> P
> >::type
> >::type
> >::type
> {};
>
> and
>
> template<int N, int M, int P, int Q>
> struct foo
> {
> enum
> {
> value = N + (M - (Q/P))
> };
>
> typedef boost::mpl::int<value> type;
> }
>
> The second version saves me a lot of template instantiations and many
> header inclusions, at the cost of losing some genericity.

It's likely to be faster, then. Compilation speed tends to vary with
number of template instantiations.

> On the other hand, if the calculation becomes complicated, I find myself
> using many enums to hold intermediate values, resulting in code like the
> following:
>
> template<class T>
> struct next_number_with_same_num_bits
> {
> enum
> {
> lowest_bit_set = T::value & (-T::value),
> lowest_bit_set_index = count_leading_zeroes<T>::type::value,
> next_t = T::value + lowest_bit_set,
> next_lowest_set_bit = next_t & (-next_t),
> mask = next_lowest_set_bit - lowest_bit_set,
> result_t = next_t | (mask >> (lowest_bit_set_index + 1))
> };
>
> typedef boost::mpl::int_<result_t> type;
> };
>
> which leads MSVC to run out of so-called compiler-keys much
> quicker than if I reduce the above to the completely unreadable:
>
> template<class T>
> struct next_number_with_same_num_bits
> {
> enum
> {
> result_t = (T::value + (T::value & (-T::value))) | ((((T::value +
> (T::value & (-T::value))) & (-T::value - (T::value & (-T::value)))) -
> (T::value & (-T::value))) >> (count_leading_zeroes<T>::type::value + 1))
> };
>
> typedef boost::mpl::int_<result_t> type;
> };
>
> Does anybody have any thoughts or comments on this technique, and is anybody
> else using tricks around MPL to make sure your compiler still handles
> things?

My advice: use the MPL constructs and optimize later. When you're
done you can measure the compilation speed difference when using
mpl::plus, minus and divides vs. the ugly version at the bottom. I
bet you dollars to donuts that it's not a significant hit. But if it
is, you can make some informed choices.

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk