在Scala上使我的List.filter更快?

时间:2011-08-23 03:45:36

标签: performance list scala filter

我正和Scala一起玩游戏。

我的游戏中有几个用于保持敌人的游泳池。它们是不可变列表,因为它们被初始化为足够的大小(因为在游戏期间创建新的敌人实例非常昂贵)。

我的游戏通过询问enemy.isVisible来了解敌人是否还活着。所以我的CollisionHandler就像:

  1. 将所有活着的敌人合并到一个列表中
  2. 获取实时子弹
  3. 对这些进行空间分割,并对同一空间分区中的子弹和敌人进行碰撞检测
  4. 让我感到沮丧的是,根据剖析器,步骤1占用了大部分时间。那一步的作用基本上是说:

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

    flatten看起来似乎并不昂贵,而是获得了getAllActive调用。它们在我的汇集特征中实现,如下所示:

    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)
    }
    

    (我省略了大部分特性,因为我认为这与此无关。)

    pool.filter是在CollisionHandler花费的总时间的45%,这看起来很奇怪。

    有什么建议可以让事情变得更快吗?

    也许使用ArrayLists而不是List?也许使用一些排序和可变集合?或者我只是做了一件可怕的错事?

    谢谢!

1 个答案:

答案 0 :(得分:4)

这些游泳池有多大?您知道每次创建列表时,都必须创建一个新对象来保存每个条目。您可以使用过滤器上的视图(即pool.view.filter(e => e.isVisible);然后返回Seq[T])来减少这一点。一般来说,我认为你的策略应该是不要每次都做额外的过滤工作。用Set或其他东西跟踪你的活跃敌人;那么当你需要它们时你会拥有它们。