1

Java で新しいエンティティ システムを構築しています。私が提案した方法が、アーキテクチャ上またはパフォーマンス上の問題を引き起こすかどうか疑問に思っています。

私が欲しい:

...

for (Entity entity : entities)
{
    for (Entry<String, Component> entry : entity.components.entrySet()) //collection is a Map
    {
        Component component = entry.getValue();
        component.update(deltaTime);
    }
}

...

対望ましくない代替手段:

...


for (Entity entity : entities)
{
    if (entity.componentA != null)
        entity.componentA.update(deltaTime);

    if (entity.componentB != null)
        entity.componentB.update(deltaTime);

    //etc. for as many components as the entity has. Finite, but possibly many.
}

...

最初のアプローチでは、HashMap アプローチに関して私が考えたことがいくつかあります。

  • 私は不必要な条件を避けます (何千ものエンティティがupdate()呼び出されている場合は自明ではありません)。
  • 読み取りアクセス時間は平均で O(1) です (取得できない可能性が高いのは、ハッシュ衝突の場合のみです)。
  • HashMap.entrySet()for-each 構文を使用してコレクションを反復処理するために呼び出す必要があります。ドキュメントからわかるように、「コレクション[セット]はマップに支えられています」。ただし、呼び出されるたびに HashMap が内部的にセットを作成しているかどうかはわかりませんentrySet()
4

2 に答える 2

2

読み取りアクセス時間は平均でO(1)です(取得できない可能性が高いのはハッシュ衝突の場合のみです)。

エントリセットのforeachループでは、を呼び出す必要はありませんmap.get()

ただし、これは、entrySet()が呼び出されるたびに、HashMapが内部でセットを作成しているかどうかを教えてくれません。

いいえ、毎回新しいセットを作成するわけではありません。


最もクリーンで読みやすく、保守しやすいコードを作成する必要があります。パフォーマンスが十分でない場合(つまり、アプリケーションのプロファイルを作成し、パフォーマンスの問題がコードのその部分に起因すると判断した場合)、最適化を開始します。

==>foreachループを使用します。

于 2012-07-18T14:39:58.193 に答える
1

最初のバージョンはほぼ間違いなく最高のデザインになるでしょう:

  • より一般的なコード - すべての可能なコンポーネント構成をカバー
  • より簡潔なコードで保守しやすい - すべての条件を避ける
  • 実行時の柔軟性が向上 - コンポーネントのリストを動的に変更できます
  • 高速 - entity.components が適切なイテレータを持つ適切なデータ構造であると仮定すると、コンポーネントごとに O(1) になるはずです

パフォーマンスが本当に重要であり、これが重要な特殊なケースであることをすでにプロファイルComponentListしている場合は、entity.components のカスタム データ構造 (例: ) を作成することを検討しupdateAll(deltaTime)てください。含有成分。これにはいくつかの利点があります。

  • Iterator オブジェクトの割り当てを回避できます (HashMap または ArrayList を使用した場合に発生します)。
  • Component タイプに特化することで、不要なキャストを回避できます
于 2012-07-18T14:47:59.903 に答える