[Effective-cpp] Item 1: Uses and Abuses of vector

White Wolf wolof at freemail.hu
Wed Oct 27 10:04:16 EDT 2004


Pal wrote:
>> ...then I guess the call to vint.end() may just be significant. But I
>> don't really like the usual solutions:
>> 
>> Solution 1, const iterator outside the loop:
>> const vector<int>::const_iterator end = vint.begin(); for
>> (vector<int>::const_iterator it = vint.begin(); it != end; ++it)
>> 
>> Solution 2, non-const iterator inside the loop:
>> for (vector<int>::const_iterator it = vint.begin(), end =
>> vint.end(); it != end; ++it) 
[SNIP]
> To mention another thing in the formula I dislike, is the redundant
> vector<int>. 
> 
> for (vint.const_iterator it = vint.begin() ...) or for
> (vint::const_iterator it = vint.begin() ...)
> 
> Would remove that.

I still did not see any proof that end() is calculated or that it is
actually cheaper to take end() out first.  But I have seen broken code too
many times, where end() was pre-evaluated and the vector (later) changed
inside the loop.  I find it a bit frustrating that noone has addressed my
question so far.  Since AFAIK end() is not necessarily calculated, as well
as even if it is it is inline, I only see a disaster waiting to happen due
to premature optimisation, and no benefit whatsoever.

Can anyone show any measurements or any fact/proof that this optimization is
actually worth the risk of broken code?  So far I could only see opinions
but not the facts they are based on.  I am not implying they aren't based on
facts, all I say is that those facts have either not been mentioned or I
have managed to miss them.  I have seen it being mentioned that end() is
calculated, while the implementation I have seen so far do not calculate
anything:

      /**
       *  Returns a read/write iterator that points one past the last
       *  element in the %vector.  Iteration is done in ordinary
       *  element order.
       */
      iterator
      end() { return iterator (_M_finish); }
      
      /**
       *  Returns a read-only (constant) iterator that points one past the
last
       *  element in the %vector.  Iteration is done in ordinary element
order.
       */
      const_iterator
      end() const { return const_iterator (_M_finish); }

The above is the g++ vector implementation of the version I have.  Based on
the HP STL implementation, as many of the current ones.  It simply returns
the value of a member, in an inline function.  This also means that copying
this out into another variable (so it is accessed from there faster) is
simply reduntant work.

So could somebody please address my questions?  I am really puzzled now,
because my experience shows that it makes no sense to pre-evaluate end()
(since it only adds the possibility of error but no speed improvements)
however all the other people discussing here seems to be absolutely
convinced about the opposite.  One of us should have slightly distorted view
of this topic, and I am more than willing to admit that I am the one - but
please give some facts you base your opinion on.

Thanks in advance,

Attila aka WW





More information about the Effective-cpp mailing list