2011-08-23 4 views
5

私はScalaでゲームを作っています。ScalaでList.filterを高速化するには?

私のゲームには、敵を守るためのプールがいくつかあります。彼らは不変のリストです。十分な大きさに初期化されているため(ゲーム中に新しい敵のインスタンスを作成するのは非常にコストがかかるためです)。

私のゲームでは、敵が生きているかどうかはenemy.isVisibleと尋ねられます。だから私のCollisionHandlerは次のように動作します:リスト

  • にすべてのライブの敵を組み合わせる

    1. 実弾
    2. をゲット宇宙パーティションこれらと同じスペースのパーティションに

    を弾丸と敵のための衝突検出を行いますプロファイラーによれば、ステップ1にはほとんどの時間がかかります。

    def allActiveEnemies = List(enemyType1.getAllActive, enemyType2.getAllActive, ...).flatten 
    

    flatten高価いないようですが、代わりにgetAllActiveのコールを取得します。そして、何そのステップはありませんが、基本的であると言います。 (私はそれはここでは関係ないと思うので、私は形質のほとんどを省略。)

    pool.filterは45%のように燃えるものです

    trait Pooled[T <: Entity] { 
        var pool = List[T]() 
        val INITIAL_POOL_SIZE:Int 
    
        def initPool() { 
         for(i<-1 to INITIAL_POOL_SIZE) 
         { 
          addToPool(disable(createNew)) 
         } 
        } 
    
        def getAllActive:List[T] = pool.filter(e => e.isVisible) 
    } 
    

    :彼らはこのような私のプールされた特性に実装されていますCollisionHandlerで費やされた合計時間。これは本当に不思議なことです。

    ここで物事をより速くするための提案はありますか?

    Listの代わりにArrayListを使用していますか?たぶんいくつかの並べ替えと変更可能なコレクションを使用して?それとも、私はひどく間違ったことをやっているのですか?

    ありがとうございます!

  • +0

    は 'e.isVisible'フィールドアクセスまたは計算ですか? – huynhjl

    +0

    isVisibleはフィールドのゲッターです(私のゲームの基礎としてJavaベースのゲームエンジンを使用しています)。 – vertti

    +0

    私はScala 2.8.1を使っていて、Android 2.x上でゲームが実行されていると付け加えるべきです。 – vertti

    答えて

    4

    これらのプールの容量はどれくらいですか?リストを作成するたびに、各エントリを保持するための新しいオブジェクトを作成する必要があることはご存じです。フィルタのビュー(例:pool.view.filter(e => e.isVisible);次にSeq[T]を返す)を使用して、これを少し減らすことができます。一般的に、私はあなたの戦略は毎回余分なフィルタリング作業をしないようにすべきだと思います。あなたの活発な敵をSetなどで追跡してください。あなたがそれらを必要とするときあなたはそれらを持っています。

    +0

    プールは現在約40で、そのうち5つがあります。しかし、我々のゲームが進むにつれて両方の数字が大きくなるので、100と10-15プールのプールサイズが推測されます。 – vertti

    +0

    @vertti - それは、まったく目に見えない時間を取るべきではありません。 –

    +0

    AndroidプロファイラはCollisionHandlerの場合約27msec、getActiveフィルタの場合は約半分と言います。 : – vertti