Reputation: 1319
I'm in WinForms and before saving changes to the DataBase, I had to check whether the used ErrorProvider holds an error for any of the displayed Controls.
I figured out several ways to do that among them:
a simple foreach loop over the ControlContainer:
foreach (Control c in ctrlcontainer)
{
if (epOrderHeader.GetError(c) != string.Empty)
{
return true;
}
}
return false;
Using the List extension Method Exists(Predicate):
return (ctrlcontainer.Exists(c => epOrderHeader.GetError(c) != string.Empty);
Right from the stomache I expected the second to be the fastest, but using the Eqatec Profiler I discovered, that the foreach loop is slightly faster (in my case about 1ms). While this is insignificant, I still wonder why this happens?
How does the compiler translate these methods and why is the first one faster?
Upvotes: 0
Views: 853
Reputation: 543
If you are using the function SetError
in the Controls inside ctrlcontainer
then you could track when an error has occurred. I would suggest either extending the class ErrorProvider
with your customized class or including that provider inside one of your classes so you can override the SetError
method i.e. you don't need to check anything and therefore the comparison between Exists
and foreach
is not relevant.
Upvotes: 0
Reputation: 22945
Why would you expect the List.Exists method to be faster? In essence it does the same as your manual check, but one thing it does do extra, is the check using a Predicate instead of a direct check. This must cost a little performance.
Upvotes: 1
Reputation: 460138
It is probably 1 ms slower in your case because List<T>.Exists
calls FindIndex
which is implemented in the following way:
public int FindIndex(int startIndex, int count, Predicate<T> match)
{
if (startIndex > this._size)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
}
if (count < 0 || startIndex > this._size - count)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
}
if (match == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
int num = startIndex + count;
for (int i = startIndex; i < num; i++)
{
if (match(this._items[i]))
{
return i;
}
}
return -1;
}
So this is a little bit more than a simple foreach
.
Upvotes: 5