2

背景:私のゲームはコンポーネントシステムを使用しています。にインスタンスのリストがあるEntityクラスがあります。私の現在の実装は次のとおりです。IComponentList<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);

このコードは現在、約0.4秒で実行されます。これは、桁違いに優れています。

Single単一のforeachループよりもはるかに効率的だと思いました。何が起きてる?

4

2 に答える 2

6

のドキュメントは次のようにSingle述べています。

シーケンスの唯一の要素を返し、シーケンスに要素が1つだけない場合は、例外をスローします。

一方First

指定された述語関数のテストに合格するシーケンスの最初の要素。

したがって、上記のループが行うことである、なしでSingleシーケンス全体をトラバースします。したがって、の代わりにまたはを使用してください。short circuitingforeachFirstFirstOrDefaultSingle

于 2012-12-03T04:53:15.837 に答える
1

シングルはコレクション全体を繰り返し、1つのアイテムのみが見つかるようにします。したがって、最高のパフォーマンスは常にO(N)です。

反復検索もO(N)パフォーマンスの影響を受けますが、これは最悪のシナリオです。

出典: List <T> .Single Method

于 2012-12-03T04:48:33.643 に答える