использовать циклы, и функции которые используют циклы только в крайней необходимости, если цикл содержит 100 итераций, но с помощью бранчей или свитча, есть возможность указать большую точность и запустить всего 25 итераций, с возможностью прерывания, лучше так сделать.
Вместо спавна, объекты можно держать в "пуле" и перезаписывать их параметры вместо спавна, будет существовать потеря памяти, но не будет никакой просадки во время "спавна" или во время работы "сборщика мусора", здесь нужно балансировать, с размерами пула -
https://ru.wikipedia.org/wiki/%D0%9E%D0 ... 1%83%D0%BB.
В остальном чем меньше вычислений происходит за один тик, тем лучше.