Delegate vs foreach loop

T

tshad

I have some code where I build a small list from a larger list and then use
this list to test with.

For example:

List<FieldName> fieldNameList = fieldNames.FindAll(delegate(FieldName
fieldName)
{ return fieldName.XMLFieldName == (string)r["tagName"]; });

The fieldName collection would be about 300 items long and the resulting
fieldNameList may be about 20.

I would then go through my smaller list of 20 to compare against a string.

My question is whether this is more efficient than:

***************************************
List<FieldName> fieldNameList = new List<FieldName>();

foreach (FieldName fn in fieldNames)
{
if (fieldName.XMLFieldName == (string)r["tagName"])
fieldNameList.Add(fieldName);
}
******************************************

In both cases, I end up with a collection of FieldNames in my new
fieldNameList.

Is the delegate way faster?

It seems to do exactly the same thing. Someone before said it was a better
way to do (less coding for one thing).

In a related question:

Is using the delegate *.Find faster or more efficient than going through a
loop like the one above?

Thanks,

Tom
 
T

tshad

Peter Duniho said:
[...]
In both cases, I end up with a collection of FieldNames in my new
fieldNameList.

Is the delegate way faster?

It seems to do exactly the same thing. Someone before said it was a
better
way to do (less coding for one thing).

I doubt that there is any significant performance difference. Using the
delegate has some extra overhead because of the invocation of the delegate
for each list member, while writing the foreach() loop explicitly yourself
might have extra overhead simply because the List<T> class might be able
to implement the iteration more efficiently (I don't know that it
does...you'd have to look at the actual implementation to know for sure).

It seems to me that the important question is what data structure do you
want to end up with? Here, it appears you actually do want a List<T>
containing the elements of interest. In that case, it seems to me to make
the most sense to use the built-in FindAll() method. It delegates the
work to the library, making your code more concise and more maintainable.

Plus, even if there's no efficiency gain now, it's possible that in the
future the List<T> implementation could actually be more efficient, and
your own code would benefit automatically without even needing to be
recompiled. (This is a purely hypothetical and probably remote
possibility, but you never know. Better to design for the future when
practical. :) ).

Note that for situtions where you _don't_ need the List<T> as a result,
it's possible that using LINQ (where, select) would make the code even
more expressive and maintainable.
In a related question:

Is using the delegate *.Find faster or more efficient than going through
a
loop like the one above?

I don't understand how this is a "related question". It looks like
basically the _same_ question to me.

Actually, it sort of is. But what I wasn't sure.

Here I am using .Find instead of .FindAll. Does .Find stop as soon as it
finds a match?

Thanks,

Tom
 
T

tshad

Peter Duniho said:
[...]
Here I am using .Find instead of .FindAll. Does .Find stop as soon as it
finds a match?

What else could it do? Are you worried that it would iterate over the
entire list, even though it only ever returns the first one found?

Actually, I was.

I was pretty sure that wasn't the case but just wanted to be sure.

Thanks,

Tom
 
G

Göran Andersson

tshad said:
I have some code where I build a small list from a larger list and then use
this list to test with.

For example:

List<FieldName> fieldNameList = fieldNames.FindAll(delegate(FieldName
fieldName)
{ return fieldName.XMLFieldName == (string)r["tagName"]; });

The fieldName collection would be about 300 items long and the resulting
fieldNameList may be about 20.

I would then go through my smaller list of 20 to compare against a string.

My question is whether this is more efficient than:

***************************************
List<FieldName> fieldNameList = new List<FieldName>();

foreach (FieldName fn in fieldNames)
{
if (fieldName.XMLFieldName == (string)r["tagName"])
fieldNameList.Add(fieldName);
}
******************************************

In both cases, I end up with a collection of FieldNames in my new
fieldNameList.

Is the delegate way faster?

It seems to do exactly the same thing. Someone before said it was a better
way to do (less coding for one thing).

In a related question:

Is using the delegate *.Find faster or more efficient than going through a
loop like the one above?

Thanks,

Tom

The performance should be about the same. The FindAll method has a bit
of extra overhead when calling the delegate, but it avoids some of the
overhead by using the internal array of the list instead of going
through the indexer or an enumerator.

Using an enumerator does protect you from unintentionally changing the
list while you are looping through it.

This will cause an exception on the first iteration as you are trying to
change the list that you are looping through:

List<int> list = new List<int>() { 1, 2, 3 };
List<int> result = new List<int>();
foreach (int value in list) {
list.Add(2);
result.Add(value);
}

This will not protect your list, but will keep adding items to it until
it eventually causes an OutOfMemoryException:

List<int> list = new List<int>() { 1, 2, 3 };
List<int> result = list.FindAll(
delegate(int value) {
list.Add(2);
return true;
}
);
 
I

Ignacio Machin ( .NET/ C# MVP )

tshad said:
I have some code where I build a small list from a larger list and then use
this list to test with.
In both cases, I end up with a collection of FieldNames in my new
fieldNameList.

Is the delegate way faster?

It seems to do exactly the same thing. Someone before said it was a better
way to do (less coding for one thing).

In a related question:

Is using the delegate *.Find faster or more efficient than going through a
loop like the one above?

I do not think that there will be a significant difference between
them both have an o(n) time (as you need to iterate once in the entire
collection).
In any case the version using the delegate have the overhead of
creating the delegate (and calling it).
But it should be minimum especially with the quantity of items you are
handling.
 

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