Boost logo

Boost :

Subject: Re: [boost] boost::signal poor performance
From: Michael Marcin (mike.marcin_at_[hidden])
Date: 2008-09-24 15:45:37


Paul Rose wrote:
> I noticed that previous e-mails hadn't mentioned platform.
>
> It is really easy to get bitten by Microsoft's "secure STL" in later
> versions of VC even in optimized release builds.
>
>> You might try -D_SECURE_SCL=0 in your command line. See
>>
>>
> http://einaros.blogspot.com/2007/02/iteration-techniques-put-on-benchmar
> k.html
>

Thanks for the link, unfortunately he doesn't release the actual
benchmark he used so I can't inspect it for validity. I assume its an
oversight in his post that he is assigning each value to sum instead of
accumulating each value in sum.

I took a little shot at recreating part of his benchmark and testing a
few more options.

Here are the results of a run on VC8 SP1 with /O2 /Ob2 and _SECURE_SCL=0
using Boost trunk at revision 48954.

Iterator accumulate took 0.39 seconds.
Pointer accumulate took 0.407 seconds.
Iterator for loop took 0.484 seconds.
Pointer for loop took 0.391 seconds.
Index for loop took 0.437 seconds.
Index for_each took 0.531 seconds.
Pointer for_each took 0.516 seconds.
BOOST_FOREACH took 1.469 seconds.
MSVC for each took 0.547 seconds.

I don't necessarily claim my benchmark to be more less valid than his
but I attached it here if anyone wants to try it themselves.

Thanks,

-- 
Michael Marcin

#include <algorithm>
#include <numeric>
#include <cstdlib>
#include <vector>
#include <iostream>
#include <boost/timer.hpp>
#include <boost/foreach.hpp>

void force_calculation( long long sum )
{
    static int count = 0;
    static volatile long long value;
    if( count && value != sum )
        {
        std::cerr << "error in run " << count << std::endl;
    }
    value = sum;
    ++count;
}

struct sum_func
{
        sum_func() : sum(0) {}
        long long sum;
        void operator()( unsigned i )
        {
                sum += i;
        }
};

int main()
{
    std::vector<unsigned> data;
    std::srand(10);
    std::generate_n(std::back_inserter(data), 100000000, &std::rand);

    {
        boost::timer timer;
                long long sum = std::accumulate( data.begin(), data.end(), 0ll );
                double elapsedtime = timer.elapsed();
                std::cout << "Iterator accumulate took " << elapsedtime << " seconds." << std::endl;
        force_calculation(sum);
    }
        {
                boost::timer timer;
                unsigned* begin = &data.front();
                long long sum = std::accumulate( begin, begin+data.size(), 0ll );
                double elapsedtime = timer.elapsed();
                std::cout << "Pointer accumulate took " << elapsedtime << " seconds." << std::endl;
                force_calculation(sum);
        }
        {
                boost::timer timer;
                long long sum = 0;
                for( std::vector<unsigned>::iterator it = data.begin(), iend = data.end(); it != iend; ++it )
                {
                        sum += *it;
                }
                double elapsedtime = timer.elapsed();
                std::cout << "Iterator for loop took " << elapsedtime << " seconds." << std::endl;
                force_calculation(sum);
        }
        {
                boost::timer timer;
                long long sum = 0;
                unsigned* it = &data.front();
                for( unsigned* iend = it+data.size(); it != iend; ++it )
                {
                        sum += *it;
                }
                double elapsedtime = timer.elapsed();
                std::cout << "Pointer for loop took " << elapsedtime << " seconds." << std::endl;
                force_calculation(sum);
        }
        {
                boost::timer timer;
                long long sum = 0;
                for( std::size_t i = 0, size = data.size(); i != size; ++i )
                {
                        sum += data[i];
                }
                double elapsedtime = timer.elapsed();
                std::cout << "Index for loop took " << elapsedtime << " seconds." << std::endl;
                force_calculation(sum);
        }
        {
                boost::timer timer;
                long long sum = std::for_each( data.begin(), data.end(), sum_func() ).sum;
                double elapsedtime = timer.elapsed();
                std::cout << "Index for_each took " << elapsedtime << " seconds." << std::endl;
                force_calculation(sum);
        }
        {
                boost::timer timer;
                unsigned* begin = &data.front();
                long long sum = std::for_each( begin, begin+data.size(), sum_func() ).sum;
                double elapsedtime = timer.elapsed();
                std::cout << "Pointer for_each took " << elapsedtime << " seconds." << std::endl;
                force_calculation(sum);
        }
        {
                boost::timer timer;
                long long sum = 0;
                BOOST_FOREACH( unsigned i, data )
                {
                        sum += i;
                }
                double elapsedtime = timer.elapsed();
                std::cout << "BOOST_FOREACH took " << elapsedtime << " seconds." << std::endl;
                force_calculation(sum);
        }
#ifdef _MSC_VER
        {
                boost::timer timer;
                long long sum = 0;
                for each( long long i in data )
                {
                        sum += i;
                }
                double elapsedtime = timer.elapsed();
                std::cout << "MSVC for each took " << elapsedtime << " seconds." << std::endl;
                force_calculation(sum);
        }
#endif
}

/* Sample results

Iterator accumulate took 0.39 seconds.
Pointer accumulate took 0.407 seconds.
Iterator for loop took 0.484 seconds.
Pointer for loop took 0.391 seconds.
Index for loop took 0.437 seconds.
Index for_each took 0.531 seconds.
Pointer for_each took 0.516 seconds.
BOOST_FOREACH took 1.469 seconds.
MSVC for each took 0.547 seconds.

*/


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