Boost logo

Boost Users :

From: Erik (sigra_at_[hidden])
Date: 2007-10-10 20:39:26


Eric Niebler skrev:
> Michael Marcin wrote:
>
>> Erik wrote:
>>
>>> Or is it possible to configure BOOST_FOREACH to be as efficient as my macro?
>> I don't know but that is a good question.
>>
>> I considered using BOOST_FOREACH until I checked its generated output...
>> which was worse than std::for_each with a boost::bind which was worse
>> than std::for_each with a hand coded functor which was worse than a hand
>> coded for loop like yours above.
>>
> I won't deny that the abstraction penalty of BOOST_FOREACH is not zero,
> but have either of you actually measured the overhead? I have, and I
> found BOOST_FOREACH to be about 5% slower than the equivalent hand-coded
> loop when compiler optimizations are turned on. It's really very small,
> and that 5% buys you a lot of expressivity. YMMV
I have not made any timings, but looked at the number of instructions in
the assembly. I assume this corresponds to code size. The good news is
that with g++-4.2.0 -O3 there appears to be no abstraction penalty at
all. BOOST_FOREACH is equivalent to the handcoded loop and my macro.
They both have 21 instructions (which appear to be equivalent; some of
them are reordered and some have their parameters swapped). But with -Os
it is possible to get only 20 instructions with handcoded/my macro,
while BOOST_FOREACH actually gives 57 instructions (-Os giving more
instructions than -O3 for ANY code looks like a compiler bug to me). And
then I tried -O2 of course. handcoded/my macro yield 21 instructions
while BOOST_FOREACH yields 31.

With g++-4.1.2 handcoded/my macro gives the same result as with
g++-4.2.0. But with BOOST_FOREACH it is another story. At -O3
BOOST_FOREACH yields as much as 28 instructions, at -O2 35 instructions
and at -Os 90 instructions.

So I suppose that as long as everyone uses g++-4.2.0 (or higher I i
suppose but did not test) and -O3 it should be fine to use
BOOST_FOREACH. Those who rely on getting small code with
-Os can forget about using BOOST_FOREACH with any of those compiler
versions.

So it seems like the gcc people did a quite good job of optimizing this
very complex hack. I suppose I will suggest that we start using
BOOST_FOREACH in our project. We already use -O3 for release builds and
in a few months (or maybe a year) almost everyone will have at least
gcc-4.2.0. But it would be interesting if others could verify my
measurements and maybe test other examples of code. I did some tests and
got the exact same results for the following use of BOOST_FOREACH (and
the corresponding use of my macro and a handcoded loop):
//////////////////////////////////////////////////////
#include <boost/foreach.hpp>

#include <vector>

void f(float);
struct A {
   void g() const;
   std::vector<float> const v;
};

void A::g() const {
   BOOST_FOREACH(float i, v)
      f(i);
}
//////////////////////////////////////////////////////


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