Boost logo

Boost :

Subject: Re: [boost] Rave for proposed Boost.Local (functions)
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-02-06 12:17:29


On Wed, Feb 2, 2011 at 2:24 AM, Jeffrey Lee Hellrung, Jr.
<jhellrung_at_[hidden]> wrote:
> Purely speculating, but I'd guess the difference in compile times could be
> quite a bit different, especially for more elaborate uses (both in terms of
> the number of template instantiations and function inlinings as well as the
> amount of header code to parse through and preprocessor code to expand).  If
> so, do you consider that a "plus" for (proposed) Boost.Local over, e.g.,
> Boost.Phoenix?
>
> It *might* also be *possible* that the higher transparency (from the
> perspective of the compiler) of functions written with (proposed)
> Boost.Local may give superior (faster, smaller, whatever) compiled code on
> some compilers than the equivalent in Boost.Phoenix.  Obviously, though, I'm
> sure you (Thomas) along with Eric, Joel, Dan Marsden, and any number of
> other boosters with vastly more experience in expression template libraries
> would be better able to assess that possibility.

Setting a side all of the Local and Phoenix comparisons which have
already been discussed enough concluding complementarity of the two
libraries as far as local functions are concerned. Unfortunately, I
cannot comment on Boost.Local performances. I can only say that *I
think* Boost.Local does more or less what Boost.ScopeExit does but I
have not studied Boost.Local performances yet.

I am posting here the code generated by the macros which might help
curious readers in spotting costly operations performed by Boost.Local
(if there are any). This of course does not include the preprocessing
time. (I hope it's not too much code... just try to get passed the
typeof noise at the beginning...)

int main() {
    double sum = 0.0;
    int factor = 10;

    // BOOST_LOCAL_FUNCTION( (void) (add)( (double)(num) (const
bind)((factor)) ) expands to:
    // Determining bound variable types (taken from Boost.ScopeExit).
    typedef void (*boost_se_tag_0_add36)(int factor );
    typedef void (*boost_se_tag_1_add36)(int &sum );
    typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap(
            boost::scope_exit::aux::deref(factor, (boost_se_tag_0_add36)0))))
            boost_se_wrapped_t_0_add36;
    typedef boost_se_wrapped_t_0_add36::type boost_se_capture_t_0_add36;
    typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap(
            boost::scope_exit::aux::deref(&sum, (boost_se_tag_1_add36)0))))
            boost_se_wrapped_t_1_add36;
    typedef boost_se_wrapped_t_1_add36::type boost_se_capture_t_1_add36;
    struct boost_se_params_t_add36 {
        typedef boost_se_capture_t_0_add36 boost_se_param_t_0_add36;
        typedef boost_se_capture_t_1_add36 boost_se_param_t_1_add36;
        boost::scope_exit::aux::member< boost_se_param_t_0_add36,
boost_se_tag_0_add36 >
                boost_se_param_0_add36;
        boost::scope_exit::aux::member< boost_se_param_t_1_add36,
boost_se_tag_1_add36 >
                boost_se_param_1_add36;
    } boost_local_auxXparams_add36 = {
          { boost::scope_exit::aux::deref(factor, (boost_se_tag_0_add36)0) }
        , { boost::scope_exit::aux::deref(&sum, (boost_se_tag_1_add36)0) }
    };
    boost::scope_exit::aux::declared< boost::scope_exit::aux::resolve<
            sizeof(boost_local_auxXargs) >::cmp1<0>::cmp2 >
boost_local_auxXargs;
    boost_local_auxXargs.value = &boost_local_auxXparams_add36;
    // Functor for the local function.
    typedef ::boost::local::function_ref< void ( double ) , 0 >
boost_local_auxXaddXref;
    struct boost_local_auxXfunctorXadd :
            ::boost::local::aux::function_base< void ( double ), 0> {
        explicit boost_local_auxXfunctorXadd(void* bind_params) :
                boost_local_auxXparams( (boost_se_params_t_add36*)
bind_params) {}
        void operator()( double num ) {
            return boost_local_auxXbody( *this
                , boost_local_auxXparams-> boost_se_param_0_add36.value
                , boost_local_auxXparams-> boost_se_param_1_add36.value
                , num
            );
        }
    private:
        boost_se_params_t_add36* boost_local_auxXparams;
        static void boost_local_auxXbody( boost_local_auxXfunctorXadd& add
            , ::boost::add_const< boost_se_params_t_add36::
boost_se_param_t_0_add36 >::type factor
            , boost_se_params_t_add36:: boost_se_param_t_1_add36 &sum
            , double num
        )

    // Programmers' write the local function body.
    {
        sum += factor * num;
        std::clog << "Summed: " << sum << std::endl;
    }

    // BOOST_LOCAL_FUNCTION_END(add) expands to:
    };
    boost_local_auxXfunctorXadd boost_local_auxXobjectXadd(
            boost_local_auxXargs.value);
    boost_local_auxXaddXref add( boost_local_auxXobjectXadd); //
Finally the actual functor...

    add(100.0);

    return 0;
}

-- 
Lorenzo

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