
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Thursday 23 July 2009, Sajjan Kalle wrote:
2009/7/23 Sajjan Kalle
: 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-----