Performance hit in foreach?

D

David Veeneman

This is a very simple question, but for moe reason I can't find an answer.
Do I take a performance hit if a foreach statement has to evaluate an
expression?

For example, consider the following:

foreach (DataColumn column in view.Row.Table.Columns)
{
// Do something
}

Do I gain anything by moving the evaluation outside the foreach, like this?

DataColumnCollection myColumns = view.Row.Table.Columns;
foreach (DataColumn column in myColumns)
{
// Do something
}

Thanks.
 
N

Nicholas Paldino [.NET/C# MVP]

David,

No, these are pretty much the same. The IEnumerable interface is going
to be obtained from the DataColumnCollection exposed by the Columns property
on the DataTable class and then the methods/properties on that
implementation are going to be accessed.

Hope this helps.
 
B

Barry Kelly

David Veeneman said:
This is a very simple question, but for moe reason I can't find an answer.
Do I take a performance hit if a foreach statement has to evaluate an
expression?

Does your application run very slowly, and does profiling show that this
area is taking a lot of time?

That's the important question to ask, IMO.

-- Barry
 
B

Bill Butler

Barry Kelly said:
Does your application run very slowly, and does profiling show that
this
area is taking a lot of time?

That's the important question to ask, IMO.

Now, often times I do agree with your advice, but not here.
Such as when somebody advocates switching from a more maintainable piece
of code to something that is harder to understand....simply in the name
of Optimization. Unless the difference is really significant...stay with
understandable code.

In David's example the first sample is a smidge easier on the eye than
the second.
Both are easy to understand and maintain.
So which to choose???
Well, all things being equal...go with the one that doesn't take the
performance hit.

Now, in this case the Hit appears to not truly exist, so David once
again can take his pick.
Sure, many people a guilty of premature optimization, but sometimes it
is a question of Best Practices.

Bill
 
B

Barry Kelly

Bill said:
Now, often times I do agree with your advice, but not here.
Such as when somebody advocates switching from a more maintainable piece
of code to something that is harder to understand....simply in the name
of Optimization. Unless the difference is really significant...stay with
understandable code.

I don't think what I said contradicted that :) But whenever someone here
agonizes over a small change like this that shouldn't affect algorithmic
complexity, whether or not it involves readability change one way or the
other, I recommend that they take it upon themselves to measure it. It's
the only way they'll really know, they'll find out how to measure
things, and hopefully they'll be aware enough of the big picture to know
when its not worth the agony. If they can't figure out these three
things, then I humbly think they might have other problems.
In David's example the first sample is a smidge easier on the eye than
the second.
Both are easy to understand and maintain.
So which to choose???
Well, all things being equal...go with the one that doesn't take the
performance hit.

If you think that the extra line doesn't amount to a de-optimization,
then this could be interpreted as an argument to use indexing on arrays
over and above foreach, for those scenarios which would work with
foreach, because there is a small performance hit for using foreach on
arrays.

Personally, I prefer fewer lines of simple code above almost everything
else, with classes written in such a way that the most performant
primitives (methods and properties etc.) are also the shortest and
simplest to use. For a concrete example, take a linked list class - such
a class shouldn't have an integer indexer, because it would make a
simple for-loop iteration a quadratic operation.
Now, in this case the Hit appears to not truly exist, so David once
again can take his pick.
Sure, many people a guilty of premature optimization, but sometimes it
is a question of Best Practices.

Again, I could interpret this as a mandate for inclusion of a certain
class of patterns into a Bible of Code Patterns, to be enforced in a
team. I think that such a Bible can be useful when the patterns matter
for correctness (e.g. think of the Dispose pattern), or for alternatives
that differ in algorithmic complexity (e.g. turning a linear algorithm
into a quadratic algorithm, with the linked list class above), but not
for things like this.

To put it another way: I think bibles of approved code patterns can work
if such a bible includes a rationale for each item (including the
qualifications above too). I'd prefer if people coding thought about
their code as they wrote it and knew what they were doing, rather than
following Best Practices on such a small scale that it can lead to
cargo-cult programming, and an attempt to turn people into cogs.

-- Barry
 
B

Bruce Wood

David said:
This is a very simple question, but for moe reason I can't find an answer.
Do I take a performance hit if a foreach statement has to evaluate an
expression?

For example, consider the following:

foreach (DataColumn column in view.Row.Table.Columns)
{
// Do something
}

No. The code you gave translates into this:

IEnumerator e = view.Row.Table.Columns.GetEnumerator();
while (e.MoveNext())
{
DataColumn column = (DataColumn)e.Current;
// Do something
}

As you can see, view.Row.Table.Columns is evaluated only once.
 
M

Mark Wilden

Does your application run very slowly, and does profiling show that this
area is taking a lot of time?

That's the important question to ask, IMO.

Agreed. I would also ask if one has read The C# Programming Language (or has
access to a copy).
 
B

Bill Butler

Barry Kelly said:
Bill Butler wrote:

Barry,

I suspect that I misread the intention of your post, becaue I find
myself agreeing with you on most evey point.
Example:
I prefer foreach over a for loop due to the increased clarity of
purpose. If I was coding a tight loop and foreach was proven to be the
bottleneck...then I would consider switching.

When I originaly read your post I took it to mean.
"If it isn't causing a problem, why are you worried."

And my thought was
"Knowledge is power, it may not matter in THIS case but it may down
the road".

I, unfortunately, have dealt with way to many developers who NEVER
consider algorithmic complexity when designing their code. It always
comes as a shock to them that it acts like a pig, because they didn't
think about such things at design time. Then, the whole thing needs to
be reworked to fix things that should have been right from the
beginning.

I can see now that you were NOT advocating :
"code it however you like as long as the performance hit is not
obvious"

Anyway,
I really should read things twice before responding.

Bill
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top