zdandoh / ecs

Golang ECS library using go generate
MIT License
5 stars 0 forks source link

Optimization match #4

Closed delaneyj closed 8 months ago

delaneyj commented 8 months ago

Like #2 there is an opportunity to fast out of Select match

case func(Entity, *comp.Position, *comp.Velocity, ) :
  for i := 0; i < currEntities; i++ {
     entity = entities[i>>entityPageBits][i%entityPageSize]
     match = match && entity.components[0] & 1 != 0
     match = match && entity.components[0] & 2 != 0

     if match {
                fun(entity, &storePosition[entity.id >> entityPageBits][entity.id % entityPageSize], &storeVelocity[entity.id >> entityPageBits][entity.id % entityPageSize], )

     }
}

If the first match is false then it could early out. Not huge in this case but with you have more components its a way to early out. The other option is to at pub/sub and have the Select have lists of entities to iterate knowing that don't have to match.

zdandoh commented 8 months ago

Nice, thanks for the suggestion. I've implemented this and it gave a small but noticeable improvement. I also moved the entities[i>>entityPageBits] pointer dereference out of the hot loop. Those two together made Select ~30% faster on my machine.

zdandoh commented 8 months ago

Looks like using a range for loop was also faster than a C style for loop, probably because it allows the compiler to elide the bounds check on the slice access. I've implemented that as well.