Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Iterator or for loop?

Reply
Thread Tools

Iterator or for loop?

 
 
Andrea Crotti
Guest
Posts: n/a
 
      12-21-2010
The "standard" way to iterate over a container should be:

std::vector<int>::iterator iter;
for (iter=var.begin(); iter!=var.end(); ++iter) {
...
}

for example, right?
But I always end up using
for (size_t i=0; i < var.size(); ++i) {
...
}

(unless I'm using maps)

because it's much shorter to write and I don't need the iterator. But
are there any real differences using this two different possibilities?
 
Reply With Quote
 
 
 
 
Joshua Maurice
Guest
Posts: n/a
 
      12-21-2010
On Dec 21, 3:09*pm, Andrea Crotti <(E-Mail Removed)> wrote:
> The "standard" way to iterate over a container should be:
>
> std::vector<int>::iterator iter;
> for (iter=var.begin(); iter!=var.end(); ++iter) {
> * * ... * *
>
> }
>
> for example, right?
> But I always end up using
> for (size_t i=0; i < var.size(); ++i) {
> * * ...
>
> }
>
> (unless I'm using maps)
>
> because it's much shorter to write and I don't need the iterator. *But
> are there any real differences using this two different possibilities?


Some compilers might optimize one better than the other. For
std::vector, I hope that both for loops would produce the same
assembly output, but I am frequently surprised as the bad quality of
some commercial compilers.

Also, some containers don't support constant time indexing, so
iterators is your only real option, such as std::map.

Also, C++0x will solve this typing annoying nicely with auto, and even
better with foreach loops aka range based for loops.
 
Reply With Quote
 
 
 
 
Chris Gordon-Smith
Guest
Posts: n/a
 
      12-22-2010
On Tue, 21 Dec 2010 15:12:49 -0800 (PST), Joshua Maurice <(E-Mail Removed)> wrote:
> On Dec 21, 3:09*pm, Andrea Crotti <(E-Mail Removed)> wrote:
>> The "standard" way to iterate over a container should be:
>>
>> std::vector<int>::iterator iter;
>> for (iter=var.begin(); iter!=var.end(); ++iter) {
>> * * ... * *
>>
>> }

I read (I think in in one of Herb Sutter's books) that this entails
calculating var.end() every time round the loop, and that using
a local variable set to var.end() can be more efficient. I wondered
whether compilers would be smart enough to optimise this without
any special user coding.

>>
>> for example, right?
>> But I always end up using
>> for (size_t i=0; i < var.size(); ++i) {
>> * * ...
>>
>> }
>>
>> (unless I'm using maps)
>>
>> because it's much shorter to write and I don't need the iterator. *But
>> are there any real differences using this two different possibilities?

>
> Some compilers might optimize one better than the other. For
> std::vector, I hope that both for loops would produce the same
> assembly output, but I am frequently surprised as the bad quality of
> some commercial compilers.
>
> Also, some containers don't support constant time indexing, so
> iterators is your only real option, such as std::map.
>
> Also, C++0x will solve this typing annoying nicely with auto, and even
> better with foreach loops aka range based for loops.
>> * * ...
>>
>> }
>>
>> for example, right? But I always end up using for (size_t i=0; i < var.size(); ++i) { * * ...
>>
>> }
>>
>> (unless I'm using maps)
>>
>> because it's much shorter to write and I don't need the iterator. *But are there any real differences using this two different
>> possibilities?

>
> Some compilers might optimize one better than the other. For std::vector, I hope that both for loops would produce the same
> assembly output, but I am frequently surprised as the bad quality of some commercial compilers.
>
> Also, some containers don't support constant time indexing, so iterators is your only real option, such as std::map.
>
> Also, C++0x will solve this typing annoying nicely with auto, and even better with foreach loops aka range based for loops.


It will be great if it allows a foreach that doesn't require the use
of a function or function object outside the loop. While I
think this technique may be useful in some cases, I think it can
be cumbersome. I recently used a foreach for what would otherwise
been a fairly straightforward loop, but found myself creating a function
object and then ensuring that it was constructed with the
right context, which would have otherwise been available in the body
of the loop 'for free'.

Chris Gordon-Smith
www.simsoup.info


 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      12-22-2010
On 12/22/10 01:46 PM, Chris Gordon-Smith wrote:
> On Tue, 21 Dec 2010 15:12:49 -0800 (PST), Joshua Maurice<(E-Mail Removed)> wrote:
>> On Dec 21, 3:09 pm, Andrea Crotti<(E-Mail Removed)> wrote:
>>> The "standard" way to iterate over a container should be:
>>>
>>> std::vector<int>::iterator iter;
>>> for (iter=var.begin(); iter!=var.end(); ++iter) {
>>> ...
>>>
>>> }

> I read (I think in in one of Herb Sutter's books) that this entails
> calculating var.end() every time round the loop, and that using
> a local variable set to var.end() can be more efficient. I wondered
> whether compilers would be smart enough to optimise this without
> any special user coding.


For std::vector, end() almost certainly optimises a way to a constant
(end doesn't have to be calculated in the loop).

>> Also, C++0x will solve this typing annoying nicely with auto, and even better with foreach loops aka range based for loops.

>
> It will be great if it allows a foreach that doesn't require the use
> of a function or function object outside the loop. While I
> think this technique may be useful in some cases, I think it can
> be cumbersome. I recently used a foreach for what would otherwise
> been a fairly straightforward loop, but found myself creating a function
> object and then ensuring that it was constructed with the
> right context, which would have otherwise been available in the body
> of the loop 'for free'.


One bit advantage of function or function objects is that they can be
testing in isolation.

--
Ian Collins
 
Reply With Quote
 
Chris Gordon-Smith
Guest
Posts: n/a
 
      12-22-2010
On 22 Dec 2010 00:46:48 GMT, Chris Gordon-Smith <(E-Mail Removed)> wrote:

Erm - sorry for the messed up formatting in my post of a few
minutes ago.

> On Tue, 21 Dec 2010 15:12:49 -0800 (PST),

Joshua Maurice <(E-Mail Removed)> wrote:
>> On Dec 21, 3:09*pm, Andrea Crotti <(E-Mail Removed)> wrote:
>>> The "standard" way to iterate over a container should be:
>>>
>>> std::vector<int>::iterator iter;
>>> for (iter=var.begin(); iter!=var.end(); ++iter) {
>>> * * ... * *
>>>
>>> }

> I read (I think in in one of Herb Sutter's books) that this entails
> calculating var.end() every time round the loop, and that using
> a local variable set to var.end() can be more efficient. I wondered
> whether compilers would be smart enough to optimise this without
> any special user coding.
>
>>>
>>> for example, right?
>>> But I always end up using
>>> for (size_t i=0; i < var.size(); ++i) {
>>> * * ...
>>>
>>> }
>>>
>>> (unless I'm using maps)
>>>
>>> because it's much shorter to write and I don't need the iterator. *But
>>> are there any real differences using this two different possibilities?

>>
>> Some compilers might optimize one better than the other. For
>> std::vector, I hope that both for loops would produce the same
>> assembly output, but I am frequently surprised as the bad quality of
>> some commercial compilers.
>>
>> Also, some containers don't support constant time indexing, so
>> iterators is your only real option, such as std::map.
>>
>> Also, C++0x will solve this typing annoying nicely with auto, and even
>> better with foreach loops aka range based for loops.

> It will be great if it allows a foreach that doesn't require the use
> of a function or function object outside the loop. While I
> think this technique may be useful in some cases, I think it can
> be cumbersome. I recently used a foreach for what would otherwise
> been a fairly straightforward loop, but found myself creating a function
> object and then ensuring that it was constructed with the
> right context, which would have otherwise been available in the body
> of the loop 'for free'.
>
> Chris Gordon-Smith
> www.simsoup.info
>
>

 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      12-22-2010
Ian Collins <(E-Mail Removed)> wrote:
>> I read (I think in in one of Herb Sutter's books) that this entails
>> calculating var.end() every time round the loop, and that using
>> a local variable set to var.end() can be more efficient. I wondered
>> whether compilers would be smart enough to optimise this without
>> any special user coding.

>
> For std::vector, end() almost certainly optimises a way to a constant
> (end doesn't have to be calculated in the loop).


Only if the compiler can prove that the vector doesn't change in the
body of the loop. That may be difficult to prove especially in cases
where the vector is being given as parameter to some function.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      12-22-2010
On 12/22/10 07:36 PM, Juha Nieminen wrote:
> Ian Collins<(E-Mail Removed)> wrote:
>>> I read (I think in in one of Herb Sutter's books) that this entails
>>> calculating var.end() every time round the loop, and that using
>>> a local variable set to var.end() can be more efficient. I wondered
>>> whether compilers would be smart enough to optimise this without
>>> any special user coding.

>>
>> For std::vector, end() almost certainly optimises a way to a constant
>> (end doesn't have to be calculated in the loop).

>
> Only if the compiler can prove that the vector doesn't change in the
> body of the loop. That may be difficult to prove especially in cases
> where the vector is being given as parameter to some function.


Did I really say constant? I should have said the call will be
optimised away. The value of end is adjusted when an insetion or
deletion occurs, rather then when end() is called.

--
Ian Collins
 
Reply With Quote
 
Fred Zwarts
Guest
Posts: n/a
 
      12-22-2010
"Chris Gordon-Smith" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)
> On Tue, 21 Dec 2010 15:12:49 -0800 (PST), Joshua Maurice
> <(E-Mail Removed)> wrote:
>> On Dec 21, 3:09 pm, Andrea Crotti <(E-Mail Removed)> wrote:
>>> The "standard" way to iterate over a container should be:
>>>
>>> std::vector<int>::iterator iter;
>>> for (iter=var.begin(); iter!=var.end(); ++iter) {
>>> ...
>>>
>>> }

> I read (I think in in one of Herb Sutter's books) that this entails
> calculating var.end() every time round the loop, and that using
> a local variable set to var.end() can be more efficient. I wondered
> whether compilers would be smart enough to optimise this without
> any special user coding.
>
>>>
>>> for example, right?
>>> But I always end up using
>>> for (size_t i=0; i < var.size(); ++i) {
>>> ...
>>>
>>> }


Similarly, this entails calculating var.size() every time round the loop.
Why should var.end() be more difficult to calculate than var.size()?
One may expect similar compiler optimizations,
or else use similar tricks using a local (const) variable.
 
Reply With Quote
 
Andrea Crotti
Guest
Posts: n/a
 
      12-22-2010
"Fred Zwarts" <(E-Mail Removed)> writes:

> Similarly, this entails calculating var.size() every time round the loop.
> Why should var.end() be more difficult to calculate than var.size()?
> One may expect similar compiler optimizations,
> or else use similar tricks using a local (const) variable.


Yes I also thought that.
Actually I thought that the "normal" for loop could have been slower for
that, and well if the container is not forced to be immutable during the
loop it should be computed every time.

From my understanding only if the container is passed as a reference to
const it should be easy (or possible) for the compiler to avoid
computing size()/end() all the time.

Correct?
 
Reply With Quote
 
Fred Zwarts
Guest
Posts: n/a
 
      12-22-2010
"Andrea Crotti" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)-aachen.de
> "Fred Zwarts" <(E-Mail Removed)> writes:
>
>> Similarly, this entails calculating var.size() every time round the
>> loop. Why should var.end() be more difficult to calculate than
>> var.size()?
>> One may expect similar compiler optimizations,
>> or else use similar tricks using a local (const) variable.

>
> Yes I also thought that.
> Actually I thought that the "normal" for loop could have been slower
> for that, and well if the container is not forced to be immutable
> during the loop it should be computed every time.
>
> From my understanding only if the container is passed as a reference
> to const it should be easy (or possible) for the compiler to avoid
> computing size()/end() all the time.
>
> Correct?


Passed to what?

If non-const references exists and can be accessed by functions called in the loop body,
these functions could still modify the container.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
List iterator assignment fails, assert iterator not dereferencable David Bilsby C++ 5 10-09-2007 02:05 PM
What makes an iterator an iterator? Steven D'Aprano Python 28 04-20-2007 03:34 AM
Difference between Java iterator and iterator in Gang of Four Hendrik Maryns Java 18 12-22-2005 05:14 AM
How to convert from std::list<T*>::iterator to std::list<const T*>::iterator? PengYu.UT@gmail.com C++ 6 10-30-2005 03:31 AM
Iterator doubts, Decision on Iterator usage greg C++ 6 07-17-2003 01:26 PM



Advertisments