-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add selector #12
base: main
Are you sure you want to change the base?
Add selector #12
Conversation
За перформанс тест есть мысли? Также важный момент. Без селектора ты на уровне верхнего итератора решаешь по чему проходиться чтобы оптимизировать запрос. С селектором такого выбора нет. Будет хорошо если он внутри будет сам смотреть каких компонентов меньше всего и их выбирать в качестве рутового иттератора. |
Тут немного по другому итерация идёт, селектор итерирует по уже известным ему сущностям, которые ему подкидывает\забирает сам мир при изменении в наборе компонентов каждой сущности.
Пока всё ещё не тестировал, но рефлексия это всегда накладно, особено если в главном цикле используется как здесь, но, имхо, удобство, которое можно сделать с его помощью, перевешывает это. Есть идея пофиксить это не ломая интерфейс с помощью необязательной кодогенерации которую можно запускать для релизного билда, а тестовые будут работать на рефлексии для быстрого запуска, т.к. го из коробки не умеет каждую компиляцию запускать кодогенератор. Этот кодогенератор будет генерировать специализированный метод |
Проблема в том, что это я так понял работает через пополнение лукап таблицы с entityid, а данные остаются в тех же плотных компонентах, верно? Если так, то это антипатерн и 100% нарушает идею ecs о плотности данных для меньших кэш миссов.
Если не регистрировать селектор, то подкидывания и рефлексии соответственно не будет, верно? Ну и рефлексия в update цикле движка это смЭрть |
На счёт удобства есть другой вариант. Сделать утилити функцию (вероятно несколько и generic) которая будет принимать компоненты и в том порядке что их приняла ходить по ним и выполнять работу. |
Да, пока селектор это просто селектор. Хранилища теже самые. Ну и в играх без использования архетипов тоже же нужно обрабатывать несколько компонентов в каждой сущности. Я ещё не углублялся в подробности реализации архетипного хранилища, пока у меня сомнения что это панацея решающая все кэш миссы. Например набор компонентов у игрока: |
В отдельный бранч закоммитил этот селектор: aled93@6123c2d в итераторе у них никакого рефлекта aled93@6123c2d#diff-2e0c4c1cbdcf5d13e3c679bd70913e595e8843a7871e352df9f10a7d95486a41R289 func (s *Selector4[T1, T2, T3, T4]) All() iter.Seq[Selector4Elements[T1, T2, T3, T4]] {
return func(yield func(Selector4Elements[T1, T2, T3, T4]) bool) {
for entId := range s.matchedEnts.Keys() {
var elems Selector4Elements[T1, T2, T3, T4]
elems.C1 = s.t1Manager.Get(entId)
elems.C2 = s.t2Manager.Get(entId)
elems.C3 = s.t3Manager.Get(entId)
elems.C4 = s.t4Manager.Get(entId)
if !yield(elems) {
break
}
}
}
} Перформанс у него повыше чем у нынешнего метода итерации по нескольким компонентам (см. скрины, первый с селектором без рефлекта, второй вообще без селекторов).
Так что теперь это не только удобство, но и +скорость :) отпишись доволен ли ты теперь, я смогу смержить в пул реквестный этот бранч через пару часов. Ещё нужно ожидать ещё больше разницы когда будет больше разнообразных компонентов, тк сейчас селектор, можно сказать, просто по всем существующим сущностям проходит, а с разнообразием не будет лишних проходов по ненужным компонентам. Попробовал в главном цикле заменить рефлект на unsafe - всё равно чуть-чуть медленее:
|
Code without selector:
and with selector:
Need performance tests