473,385 Members | 2,069 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

foreach Iterator - which is more efficient?

Everything I know about looping structures says to be careful about
expressions that need to be evaluated again and again for each
test/increment of a loop.

I came across this piece of code the other day and stopped to think for a
minute about whether it was right or not.
foreach (XmlNode node in doc.SelectNodes("/root/map/");)
{
//Do something
}

Am I missing something here or is this going to perform the Xpath select for
every iteration? Or is it the case that once the iterator has been retrieved
by the foreach statement that it will use the same one for each loop without
evaluating the SelectNodes statement over and over again.

If I was able to read IL - I would look at what was going on here myself.

I've been trained to think about doing this the following way.

XmlNodeList list = doc.SelectNodes("/root/map/");
foreach (XmlNode node in list)
{
//Do something
}

Enlightenment appreciated....
Feb 22 '06 #1
9 7728
I'm not sure if the compiler is smart enough to optimize this, but number 2
is definitely the way to go in my book.
Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"Anthony Bouch" wrote:
Everything I know about looping structures says to be careful about
expressions that need to be evaluated again and again for each
test/increment of a loop.

I came across this piece of code the other day and stopped to think for a
minute about whether it was right or not.
foreach (XmlNode node in doc.SelectNodes("/root/map/");)
{
//Do something
}

Am I missing something here or is this going to perform the Xpath select for
every iteration? Or is it the case that once the iterator has been retrieved
by the foreach statement that it will use the same one for each loop without
evaluating the SelectNodes statement over and over again.

If I was able to read IL - I would look at what was going on here myself.

I've been trained to think about doing this the following way.

XmlNodeList list = doc.SelectNodes("/root/map/");
foreach (XmlNode node in list)
{
//Do something
}

Enlightenment appreciated....

Feb 22 '06 #2
Anthony,
Or is it the case that once the iterator has been retrieved
by the foreach statement that it will use the same one for each loop without
evaluating the SelectNodes statement over and over again.
Yes.

If I was able to read IL - I would look at what was going on here myself.


You don't have to be able to read IL. Just check the C# documentation
on how the foreach statement is compiled to a single call to
GetEnumerator (usually from the IEnumerable or IEnumerable<T>
interfaces).
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Feb 22 '06 #3
Compiler generate this:

XmlDocument doc = new XmlDocument();

XmlNodeList list = doc.SelectNodes("/root/map/");

IEnumerator enumerator = list.GetEnumerator();
try
{
XmlNode node;
while (enumerator.MoveNext())
{
node = (XmlNode)enumerator.Current;
// DO SMTH
}
}
finally
{
IDisposable disposable = (IDisposable)enumerator;
if (disposable != null)
disposable.Dispose();
}

Feb 22 '06 #4
Anthony,

The following code produced the *exact* same MSIL for the foreach loop
on my C# 1.1 compiler. As you can see the SelectNodes method is only
executed once.

IEnumerator enumerator = doc.SelectNodes("/root/map/");
try
{
while (enumerator.MoveNext())
{
XmlNode node = (XmlNode)enumerator.Current;
}
}
finally
{
IDisposable disposable = enumerator as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}

Personally, I prefer the first method you described because it keeps
the scope of local variables as narrow as possible and yet is still
very readable.

Brian

Anthony Bouch wrote:
Everything I know about looping structures says to be careful about
expressions that need to be evaluated again and again for each
test/increment of a loop.

I came across this piece of code the other day and stopped to think for a
minute about whether it was right or not.
foreach (XmlNode node in doc.SelectNodes("/root/map/");)
{
//Do something
}

Am I missing something here or is this going to perform the Xpath select for
every iteration? Or is it the case that once the iterator has been retrieved
by the foreach statement that it will use the same one for each loop without
evaluating the SelectNodes statement over and over again.

If I was able to read IL - I would look at what was going on here myself.

I've been trained to think about doing this the following way.

XmlNodeList list = doc.SelectNodes("/root/map/");
foreach (XmlNode node in list)
{
//Do something
}

Enlightenment appreciated....


Feb 22 '06 #5
Peter Bromberg [C# MVP] <pb*******@yahoo.nospammin.com> wrote:
I'm not sure if the compiler is smart enough to optimize this, but number 2
is definitely the way to go in my book.


Why? It's less readable, leaves an extra variable in scope for no good
reason, and won't perform any better anyway :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 22 '06 #6
Anthony Bouch <an*****@nospamforever.com> wrote:
Everything I know about looping structures says to be careful about
expressions that need to be evaluated again and again for each
test/increment of a loop.

I came across this piece of code the other day and stopped to think for a
minute about whether it was right or not.
foreach (XmlNode node in doc.SelectNodes("/root/map/");)
{
//Do something
}

Am I missing something here or is this going to perform the Xpath select for
every iteration? Or is it the case that once the iterator has been retrieved
by the foreach statement that it will use the same one for each loop without
evaluating the SelectNodes statement over and over again.
Exactly. If it were re-executing SelectNodes each time, you'd keep
getting the first element of the list :)
If I was able to read IL - I would look at what was going on here myself.


Fortunately there's the C# spec to go on as well :)

From the ECMA spec, section 15.8.4:

<quote>
A foreach statement of the form:

foreach (ElementType element in collection) statement

corresponds to one of two possible expansions:

If the collection expression is of a type that implements the
collection pattern (as defined above), the expansion of the foreach
statement is:

<snip - this isn't the normal case>

Otherwise; the collection expression is of a type that implements
System.IEnumerable, and the expansion of the foreach statement is:

IEnumerator enumerator =
((System.IEnumerable)(collection)).GetEnumerator() ;
try {
while (enumerator.MoveNext()) {
ElementType element = (ElementType)enumerator.Current;
statement;
}
}
finally {
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
}

</quote>

Note that the "collection" expression is only evaluated once.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 22 '06 #7
Overwhelmed with the replies - totally clear now and slightly embarrassed
that I didn't check the documentation first.

Thanks

"Anthony Bouch" <an*****@nospamforever.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Everything I know about looping structures says to be careful about
expressions that need to be evaluated again and again for each
test/increment of a loop.

I came across this piece of code the other day and stopped to think for a
minute about whether it was right or not.
foreach (XmlNode node in doc.SelectNodes("/root/map/");)
{
//Do something
}

Am I missing something here or is this going to perform the Xpath select
for every iteration? Or is it the case that once the iterator has been
retrieved by the foreach statement that it will use the same one for each
loop without evaluating the SelectNodes statement over and over again.

If I was able to read IL - I would look at what was going on here myself.

I've been trained to think about doing this the following way.

XmlNodeList list = doc.SelectNodes("/root/map/");
foreach (XmlNode node in list)
{
//Do something
}

Enlightenment appreciated....

Feb 23 '06 #8
Anthony,

I thought it was a good question. And as far as the documentation is
concerned I understand that sometimes you just don't know what keywords
to search on to find what you want. I did a little poking around and
the only place I found that clearly explained how the foreach construct
is compiled was the C# specification (MSDN or ECMA versions).

Brian

Anthony Bouch wrote:
Overwhelmed with the replies - totally clear now and slightly embarrassed
that I didn't check the documentation first.

Thanks


Feb 23 '06 #9
Anthony Bouch <an*****@nospamforever.com> wrote:
Overwhelmed with the replies - totally clear now and slightly embarrassed
that I didn't check the documentation first.


No need for embarrassment. Yes, it's documented - but unless you knew
where to go, it wasn't exactly staring you in the face.

Put it this way - it was a lot less trivial than a lot of questions we
get here :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 23 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: nick | last post by:
Hi, I need to manage a "layered" collection of objects, where each layer grows independently, e.g, o--+--+--+--+--+ 1st layer | o 2nd layer (empty) | o--+--+--+ 3rd...
8
by: cody | last post by:
currently, foreach takes a IEnumerable as parameter, so we can do: foreach (int i in array){} what about an additional form of foreach that takes an IEnumerator as parameter, so we can do: ...
1
by: bearophileHUGS | last post by:
The Digital Mars D compiler is a kind of "improved c++", it contains a "foreach" statement: http://www.digitalmars.com/d/statement.html#foreach Usage example: foreach(int i, inout int p; v1) p...
15
by: Fabio Cannizzo | last post by:
Is it possible to do something similar to the STL iterators, i.e. to execute a foreach loop in reverse order? Thanks, Fabio
2
by: Ryan Liu | last post by:
Hi, I heard foreach is slower then use loop directly, is that really true? When loop though a list in a multiple thread environment, is that a good practice to copy this list to an array the...
16
by: mailforpr | last post by:
How do I do that? The thing is, the only information I have about the iterator is the iterator itself. No container it is belonging to or anything. Like template<Iteratorvoid...
13
by: Tamagafk | last post by:
Hi! Looks like there is a bug in php. If I have function which uses foreach to run trough array recursively, the lop-level foreach interupted by lover-level foreach'es. If I use simply 'for'...
9
by: news.microsoft.com | last post by:
I am looping through an iteration and I would like to test the next item but if its not the one that I want how do I put it back so that when my foreach continues it is in the next iteration? ...
4
by: Peter Morris | last post by:
I am not sure what you are asking. You seem to be asking how to implement a plain IEnumerable on a composite structure, but then your example shows a flat structure using "yield". Your subject...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.