Сделать мой List.filter быстрее на Scala? - PullRequest
5 голосов
/ 23 августа 2011

Я делаю игру со Scala.

В моей игре есть несколько пулов для хранения врагов.Они являются неизменяемыми списками, потому что они инициализируются до размера, который должен быть достаточным (поскольку создание новых экземпляров врага во время игры очень дорого).

Моя игра знает, жив ли враг, спрашивая enemy.isVisible.Таким образом, мой CollisionHandler работает следующим образом:

  1. Объедините всех живых врагов в список
  2. Получите живые пули
  3. Разбейте их и выполните обнаружение столкновений для пуль и врагов втот же раздел пространства

Меня поразило то, что, согласно профилировщику, шаг 1 занимает большую часть времени.И то, что делает этот шаг, в основном говорит:

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

flatten там не кажется дорогим, но вместо этого он получает вызовы getAllActive.Они реализованы в моей черте Pooled следующим образом:

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 - это то, что горит как45% от общего времени, проведенного в CollisionHandler, что кажется странным.

Есть предложения по ускорению процесса?

Может быть, использовать ArrayLists вместо List?Может быть, использовать сортировку и изменяемые коллекции?Или я просто что-то делаю ужасно неправильно?

Спасибо!

1 Ответ

4 голосов
/ 23 августа 2011

Насколько велики эти бассейны?Вы знаете, что каждый раз, когда вы делаете список, вы должны создать новый объект для хранения каждой записи.Вы можете немного сократить это, используя вид на фильтр (то есть pool.view.filter(e => e.isVisible); затем верните Seq[T]).В общем, я думаю, что ваша стратегия должна заключаться в том, чтобы каждый раз не выполнять дополнительную работу по фильтрации.Следите за своими активными врагами в Set или что-то;тогда они у вас есть, когда они вам нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...