Boost logo

Boost Users :

Subject: Re: [Boost-users] [Signals] Another performance discussion
From: Frank Mori Hess (frank.hess_at_[hidden])
Date: 2009-07-23 15:26:59


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Thursday 23 July 2009, Sajjan Kalle wrote:
> 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.

On what kind of hardware? On a 3.2GHz Pentium D running Linux with gcc
4.3.2 , I get:

$ g++ -Wall -O2 -I /usr/local/boost-1_39_0/include/boost-1_39/
sigbench.cpp -lboost_signals-gcc43-mt
$ ./a.out
vector variant: 0.12
boost::signal Unfragmented variant: 0.89
boost::signal Fragmented variant: 2
$ ./a.out
vector variant: 0.12
boost::signal Unfragmented variant: 0.52
boost::signal Fragmented variant: 2.07

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkpouYQACgkQ5vihyNWuA4VvzACfQBxHw5tzpoDCAiocQLgmUrNW
eLkAmgLTvPVbHoDMeV28vg60UAQ9U8cC
=f5c+
-----END PGP SIGNATURE-----


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