#include "Connection.hpp" #include "Signal.hpp" #include "boost/signal.hpp" #include "boost/bind.hpp" #include "boost/date_time/posix_time/posix_time_types.hpp" #include #include #include struct X { X(int x = 0) : x_(x) { } int x_; }; void foo(X & x) { x.x_ += 1234; } void blarg(X & x) { x.x_ /= 71; } struct bar { void operator()(X & x) { x.x_ *= 7; } }; struct foobar { void doit(X & x) { x.x_ += 7; } }; struct timing { size_t nslots_; size_t ncalls_; double elapsed1_; double elapsed2_; }; inline double as_double( boost::posix_time::time_duration const & duration) { double result = duration.ticks(); return result /= duration.ticks_per_second(); } int main( int argc, char * argv[]) { try { std::vector timings; size_t num_slots[] = { 1, 10, 50, 100, 250, 500, 1000, 5000, 10000, 50000, 100000, 500000, 0 }; typedef lite::signals::Signal Signal1; Signal1 signal1; typedef boost::signal Signal2; Signal2 signal2; size_t totcalls[] = { 1000, 10000, 100000, 1000000, 0 }; for (size_t * tc = totcalls; *tc > 0; ++tc) { size_t total_calls = *tc; for (size_t * ns = num_slots; *ns > 0 && *ns <= total_calls; ++ns) { size_t nslots = *ns; size_t niters = total_calls / nslots; signal1.disconnect_all_slots(); signal1.connect(bar()); foobar foobar1; signal1.connect(boost::bind(&foobar::doit, &foobar1, _1)); signal2.disconnect_all_slots(); signal2.connect(bar()); foobar foobar2; signal2.connect(boost::bind(&foobar::doit, &foobar2, _1)); std::vector slots(nslots); for (size_t i = 0; i < slots.size(); ++i) { signal1.connect(boost::bind(&foobar::doit, &slots[i], _1)); signal2.connect(boost::bind(&foobar::doit, &slots[i], _1)); } X my_x(5); timing t; t.nslots_ = nslots; t.ncalls_ = niters; boost::posix_time::ptime start_time( boost::posix_time::microsec_clock::local_time()); for (size_t i = 0; i < niters; ++i) { signal1(my_x); } boost::posix_time::ptime stop_time( boost::posix_time::microsec_clock::local_time()); t.elapsed1_ = as_double(stop_time - start_time); X bs_x(5); start_time = boost::posix_time::microsec_clock::local_time(); for (size_t i = 0; i < niters; ++i) { signal2(bs_x); } stop_time = boost::posix_time::microsec_clock::local_time(); t.elapsed2_ = as_double(stop_time - start_time); timings.push_back(t); if (my_x.x_ != bs_x.x_) { std::cerr << "my_x(" << my_x.x_ << ") != bs_x(" << bs_x.x_ << ")\n"; } } } size_t last_size = (size_t)-1; for (size_t i = 0; i < timings.size(); ++i) { if (last_size != timings[i].nslots_ * timings[i].ncalls_) { last_size = timings[i].nslots_ * timings[i].ncalls_; fprintf(stdout, "\n===== %u Total Calls =====\n", last_size); fprintf(stdout, "Num Slots Calls/Slot Boost Lite\n"); fprintf(stdout, "--------- ---------- ------- -------\n"); } fprintf(stdout, "%9u%14u%11.4f%10.4f\n", timings[i].nslots_, timings[i].ncalls_, timings[i].elapsed2_, timings[i].elapsed1_); } return 0; } catch (std::exception const & ex) { std::cerr << "exception: " << ex.what() << std::endl; } return 1; }