为什么List <T> .Exists比foreach循环慢?

bud*_*ble 0 c# loops generic-list

我在WinForms中,在保存对DataBase的更改之前,我必须检查使用的ErrorProvider是否为任何显示的控件保留错误.

我想出了几种方法可以做到这一点:

  • 一个简单的foreach循环在ControlContainer上:

        foreach (Control c in ctrlcontainer)
        {
            if (epOrderHeader.GetError(c) != string.Empty)
            {
                return true;
            }
        }
        return false;
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用List扩展方法Exists(谓词):

    return(ctrlcontainer.Exists(c => epOrderHeader.GetError(c)!= string.Empty);

从胃口开始,我预计第二个是最快的,但是使用我发现的Eqatec Profiler,foreach循环稍微快一些(在我的情况下大约1ms).虽然这是微不足道的,但我仍然想知道为什么会这样?

编译器如何翻译这些方法,为什么第一个更快?

Tim*_*ter 5

在你的情况下它可能慢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;
}
Run Code Online (Sandbox Code Playgroud)

所以这不仅仅是一个简单的问题foreach.