簡體   English   中英

為什么列出 <T> 存在比foreach循環慢嗎?

[英]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方法,即,您無需檢查任何內容,因此Existsforeach之間的比較不相關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM