单一呼叫的Linq缓慢

ash*_*999 2 c# linq optimization

背景:我的游戏正在使用组件系统.我有一个Entity类,其中包含一个IComponent实例列表List<IComponent>.我目前的实施Entity.GetComponent<T>()是:

return (T)this.components.Single(c => c is T);

添加碰撞检测后,我注意到我的游戏降至1FPS.剖析揭示了这个电话的罪魁祸首(每帧称为3000+次).

除了3000x之外,我注意到调用这300k次大约需要2秒钟.我将它优化为一个简单的迭代循环:

foreach (IComponent c in this.components) { 
  if (c is T) {
    return (T)c; 
  }
}

return default(T);
Run Code Online (Sandbox Code Playgroud)

此代码现在运行大约0.4秒,这是一个数量级更好.

我认为Single比单个foreach循环更有效.这里发生了什么?

Can*_*ide 6

该文件Single说:

返回序列的唯一元素,如果序列中没有一个元素,则抛出异常.

另一方面First:

序列中的第一个元素,它在指定的谓词函数中传递测试.

所以,Single你没有遍历整个序列short circuiting,这就是foreach上面的循环.所以,使用FirstFirstOrDefault代替Single.