[英]Why is List<T>.Exists slower than a foreach loop?
我在WinForms中,在將更改保存到數據庫之前,我必須檢查所使用的ErrorProvider是否對任何顯示的控件都持有錯誤。
我想出了幾種方法來做到這一點:
ControlContainer上的一個簡單的foreach循環:
foreach (Control c in ctrlcontainer) { if (epOrderHeader.GetError(c) != string.Empty) { return true; } } return false;
使用列表擴展方法Exists(Predicate):
return(ctrlcontainer.Exists(c => epOrderHeader.GetError(c)!= string.Empty);
從肚子開始,我希望秒數是最快的,但是使用我發現的Eqatec Profiler,foreach循環稍快(在我的情況下約為1ms)。 盡管這無關緊要,但我仍然想知道為什么會這樣嗎?
編譯器如何翻譯這些方法,為什么第一個方法更快?
在您的情況下,它可能要慢1毫秒,因為List<T>.Exists
調用FindIndex
,它是通過以下方式實現的:
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;
}
因此,這不僅僅是簡單的foreach
。
您為什么期望List.Exists方法更快? 從本質上講,它執行與手動檢查相同的操作,但是它做的另一件事是使用謂詞而不是直接檢查來進行檢查。 這必須花費一點性能。
如果您在ctrlcontainer
內部的控件中使用功能SetError
,則可以跟蹤何時發生錯誤。 我建議您使用自定義的類擴展ErrorProvider
類,或者在您的一個類中包括該提供者,以便您可以覆蓋SetError
方法,即,您無需檢查任何內容,因此Exists
和foreach
之間的比較不相關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.