I would hazard a guess that you are using MSVC with _SECURE_SCL left as the default ON.
Here are my results with _SECURE_SCL on:
Time: BOOST_FOREACH(Fred& fred, vec) { fred.inc(); } 1.406
Time: std::for_each(vec.begin(),vec.end(),boost::bind(&Fred::inc,_1) ); 0.515
Time: for (std::vector<Fred>::iterator i = vec.begin(); i < theEnd ; i++) { (*i).inc(); } 1.313
Time: std::for_each(vec.begin();vec.end(),std::mem_fun_ref(&Fred::inc)) 0.516
Time: for (size_t i = 0; i < theSize ; i++) { vec[i].inc(); } 0.391
And with _SECURE_SCL off:
Time: BOOST_FOREACH(Fred& fred, vec) { fred.inc(); } 0.36
Time: std::for_each(vec.begin(),vec.end(),boost::bind(&Fred::inc,_1) ); 0.515
Time: for (std::vector<Fred>::iterator i = vec.begin(); i < theEnd ; i++) { (*i).inc(); } 0.344
Time: std::for_each(vec.begin();vec.end(),std::mem_fun_ref(&Fred::inc)) 0.516
Time: for (size_t i = 0; i < theSize ; i++) { vec[i].inc(); } 0.375
So you can see that going through a function pointer has an abstraction penalty - but this is basically the same whether it be through bind or std::mem_fun_ref (haven't checked but assume they compile to same optimized code)
Iterators are faster than indexes if _SECURE_SCL is off and slower if it is on - no new news here. ForEach has a small penalty over iterators, but is rare that this matters.
Pete
On Fri 05/02/10 15:13 , Avi Bahra <avibahra@googlemail.com> wrote:
In my application I have very large data sets, I was using BOOST_FOREACH
and boost bind. But I was surprised that performance wise they were the worst ?
Take the following test:
class Fred {
public:
Fred(int i = 0) : i_(i) {}
void inc() { i_++;}
private:
int i_;
};
BOOST_AUTO_TEST_CASE( test_loop )
{
size_t vecSize = 200000000;
std::vector<Fred> vec; vec.reserve(vecSize);
for (size_t i = 0; i < vecSize ; i++) { vec.push_back(Fred(i));}
boost::timer timer;
BOOST_FOREACH(Fred& fred, vec) { fred.inc(); }
cout << "Time: BOOST_FOREACH(Fred& fred, vec) { fred.inc(); } " << timer.elapsed() << "\n";
timer.restart();
std::for_each(vec.begin(),vec.end(),boost::bind(&Fred::inc,_1) );
cout << "Time: std::for_each(vec.begin(),vec.end(),boost::bind(&Fred::inc,_1) ); " << timer.elapsed() << "\n";
timer.restart();
std::vector<Fred>::iterator theEnd = vec.end();
for (std::vector<Fred>::iterator i = vec.begin(); i < theEnd ; i++) { (*i).inc(); }
cout << "Time: for (std::vector<Fred>::iterator i = vec.begin(); i < theEnd ; i++) { (*i).inc(); } " << timer.elapsed() << "\n";
timer.restart();
std::for_each(vec.begin(),vec.end(),std::mem_fun_ref(&Fred::inc) );
cout << "Time: std::for_each(vec.begin();vec.end(),std::mem_fun_ref(&Fred::inc)) " << timer.elapsed() << "\n";
timer.restart();
size_t theSize = vec.size();
for (size_t i = 0; i < theSize ; i++) { vec[i].inc(); }
cout << "Time: for (size_t i = 0; i < theSize ; i++) { vec[i].inc(); } " << timer.elapsed() << "\n";
}
I get following times when run on suse linux with gcc 4.2.1/ boost 1.39
Time: BOOST_FOREACH(Fred& fred, vec) { fred.inc(); } 10.65
Time: std::for_each(vec.begin(),vec.end(),boost::bind(&Fred::inc,_1) ); 9.76
Time: for (std::vector<Fred>::iterator i = vec.begin(); i < theEnd ; i++) { (*i).inc(); } 4.48
Time: std::for_each(vec.begin();vec.end(),std::mem_fun_ref(&Fred::inc)) 4.08
Time: for (size_t i = 0; i < theSize ; i++) { vec[i].inc(); } 1.6
It appears that BOOST_FOREACH and use of boost::bind in performance critical
application should be avoided ?
--
Best regards,
Ta,
Avi