Boost logo

Boost Users :

Subject: Re: [Boost-users] [Signals] Another performance discussion
From: Sajjan Kalle (sairony_at_[hidden])
Date: 2009-07-23 11:43:30


2009/7/23 Sajjan Kalle <sairony_at_[hidden]>:
> Profiling the project in question where the performance of
> boost::signals is one of the problems it seems two of the bottlenecks
> is slot_call_iterator::increment and slot_call_iterator::equal, and in
> those in particular find_if, which seems to be used for incrementing
> the iterator. I'll try to create a sample with timing on a bit more
> fragmented world like use case.
>

I'll throw signals2 in to the mix once I've built 1.39, in the
meantime, here's a new variant which depends on only stl and boost.

#include <iostream>
#include "boost/signals.hpp"
#include <vector>
#include "boost/function.hpp"
#include "boost/timer.hpp"
#include <cstdlib>
#include <algorithm>

void foo( )
{
}

int main()
{
        std::vector< boost::function< void ( void ) > > manualSignal;
        boost::signal< void ( void ) > boostSignalFragmented, boostSignalUnfragmented;
        typedef std::vector< boost::signals::connection > ConnectionVector;
        ConnectionVector connections;
        for( unsigned int i = 0; i < 10000; ++i )
        {
                manualSignal.push_back( &foo );
                boostSignalUnfragmented.connect( &foo );
        }
        for( unsigned int i = 0; i < 100000; ++i )
        {
                connections.push_back( boostSignalFragmented.connect( &foo ) );
        }
        for( unsigned int i = 0; i < 90000; ++i )
        {
                ConnectionVector::iterator index = connections.begin() + rand() %
connections.size();
                (*index).disconnect();
                *index = *connections.rbegin();
                connections.erase( connections.begin() + connections.size() - 1 );
        }
        {
                boost::timer tm;
                for( unsigned int i = 0; i < 1000; ++i )
                {
                        for( unsigned int j = 0; j < 10000; ++j )
                                manualSignal[ i ]( );
                }
                double elapsed = tm.elapsed();
                std::cout << "vector variant: " << elapsed << std::endl;
        }
        {
                boost::timer tm;
                for( unsigned int i = 0; i < 1000; ++i )
                {
                        boostSignalUnfragmented( );
                }
                double elapsed = tm.elapsed();
                std::cout << "boost::signal Unfragmented variant: " << elapsed << std::endl;
        }
        {
                boost::timer tm;
                for( unsigned int i = 0; i < 1000; ++i )
                {
                        boostSignalFragmented( );
                }
                double elapsed = tm.elapsed();
                std::cout << "boost::signal Fragmented variant: " << elapsed << std::endl;
        }
}

This gives me ~0.032 on vector, ~1.80 on unfragmented boost::signal
and lastly ~3.04 on fragmented boost::signal.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net