Boost logo

Boost :

Subject: Re: [boost] [local] Help for the Alternatives section
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-04-03 13:23:33


On Mon, Mar 28, 2011 at 2:50 AM, Thomas Heller
<thom.heller_at_[hidden]> wrote:
> On Monday, March 28, 2011 05:25:13 AM Jeremy Maitin-Shepard wrote:
>> On 03/26/2011 03:19 PM, Lorenzo Caminiti wrote:
>> > Hello all,
>> >
>> > I am updating Boost.Local docs and I could use a some help in getting
>> > the Alternatives section right
>> >
> http://svn.boost.org/svn/boost/sandbox/local/libs/local/doc/html/boost_local/Alternatives.html
>>
>> You might include compile time and run time benchmarks, information
>> about error message quality, and polymorphic capabilities.
>> Additionally, you might note that with C++0x local classes can be used
>> with templates.
>
> Just did a quick test ... code is attached ...
>
> $ time g++  -O3 -I. -Wall -Wextra add.cpp -o add
>
> real    0m0.657s
> user    0m0.583s
> sys     0m0.067s
>
> $ time ./add
> 1e+12
>
> real    0m35.641s
> user    0m35.618s
> sys     0m0.017s
>
> $ time g++ -O3 -I. -Wall -Wextra add_boost_phoenix.cpp -o add_phoenix
>
> real    0m3.385s
> user    0m3.160s
> sys     0m0.217s
> thomas_at_sunshine ~/programming/local $ time ./add_phoenix
> 1e+12
>
> real    0m6.648s
> user    0m6.643s
> sys     0m0.007s

I have done an (hopefully more correct) benchmark of Boost.Local
performances compared with the alternative methods -- please check my
doing :)

In summary:
1) Boost.Phoenix, global functors, and local functors run in ~15s.
2) Boost.Lambda runs in ~40s.
3) Boost.Local runs in ~53s.
4) I don't have a C++0x lambda compiler so I could not benchmark C++0x lambdas.

I don't know why Boost.Lambda takes longer than 1). Boost.Local seems
to take longer than 1) because of the extra virtual function call
introduced by the trick that allows to pass the local struct as a
template parameter -- I will follow up with another email to explain
this point in detail.

ANALYSIS

The basic code looks like this (see attachments):

#define N 10000

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

    void BOOST_LOCAL_FUNCTION_PARAMS( (const double& num)
            (bind& sum) (const bind& factor) ) {
        sum += factor * num;
    } BOOST_LOCAL_FUNCTION_NAME(add)

    std::vector<double> v(N * 100);
    std::fill(v.begin(), v.end(), 10);
    for (size_t n = 0; n < N; ++n) {
        std::for_each(v.begin(), v.end(), add);
    }

    std::cout << sum << std::endl;
    return 0;
}

BOOST LOCAL

$ time g++ -O3 -I../../.. -Wall -Wextra benchmark_boost_local.cpp

real 0m8.330s
user 0m1.166s
sys 0m1.463s

$ time ./a
1e+12

real 0m52.735s
user 0m52.109s
sys 0m0.077s

GLOBAL FUNCTOR

$ time g++ -O3 -I../../.. -Wall -Wextra benchmark_global_functor.cpp

real 0m5.302s
user 0m0.573s
sys 0m0.560s

$ time ./a
1e+12

real 0m15.167s
user 0m14.499s
sys 0m0.030s

LOCAL FUNCTOR (manual for-loop instead of for_each)

$ time g++ -O3 -I../../.. -Wall -Wextra benchmark_local_functor.cpp

real 0m5.476s
user 0m0.510s
sys 0m0.730s

$ time ./a
1e+12

real 0m15.392s
user 0m14.686s
sys 0m0.108s

BOOST LAMBDA

$ time g++ -O3 -I../../.. -Wall -Wextra benchmark_boost_lambda.cpp

real 0m6.631s
user 0m0.792s
sys 0m1.199s

$ time ./a
1e+12

real 0m39.855s
user 0m38.905s
sys 0m0.061s

BOOST PHOENIX

$ time g++ -O3 -I../../.. -Wall -Wextra benchmark_boost_phoenix.cpp

real 0m14.004s
user 0m3.761s
sys 0m3.543s

$ time ./a
1e+12

real 0m15.727s
user 0m14.921s
sys 0m0.030s

-- 
Lorenzo

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