Чему я научился после миграции на DOTS/ECS
Мы перевели часть продакшен-проекта на ECS, и время кадра упало на 34 %. Но выигрыш пришёл не оттуда, откуда мы ждали.
Почему мы мигрировали
На экране одновременно было около 3000 движущихся сущностей, и в профайлере каждый раз наверху стояло одно и то же: сумма вызовов MonoBehaviour.Update и вызванные ими промахи кеша.
Цель никогда не была в том, чтобы перевести всё на ECS. Мы перенесли только то, что многочисленно, однородно и плотно: снаряды, юниты роя, логику частиц.
Настоящий выигрыш — в раскладке памяти
Все говорят о Burst и SIMD. В наших замерах разница пришла не оттуда, а из того, что данные лежат в памяти подряд.
Разрыв между чтением 3000 объектов поодиночке из кучи и чтением 3000 позиций подряд из массива дал до восьмикратной разницы во времени при одинаковой математике.
Цена гибридной архитектуры
Поскольку мы не ушли в ECS полностью, пришлось строить мост между двумя мирами. Этот мост дал куда больше работы, чем мы закладывали.
Совет: чётко проведите границу с самого начала. Какие системы живут на стороне ECS, какие остаются классическими и односторонний ли поток данных между ними — решите это до написания кода.
Когда не стоит
Если число сущностей не переваливает за пару сотен, привносимая ECS сложность перевешивает выигрыш. Если команда не знает ECS, посчитайте и стоимость обучения.
Я использую простой порог: если больше 500 объектов выполняют одно и то же поведение и обновляются каждый кадр, переносить стоит.