Skip to content

Allow Option<Entity> to use memory layout optimization #3022

Closed
@notverymoe

Description

@notverymoe

What problem does this solve or what need does it fill?

Entity currently can't be default constructed or represent a "never valid" entity. Which is extremely useful for sparse relational data structures like grids and oct/quadtrees. This is easily sidestepped via Option<Entity>, as rust does - so there's not a hard limit here or anything of course.

The issue is that Option will introduce some memory overhead, which can become significant in flatter data structures like grids.

What solution would you like?

I'd like to be allow the compiler to leverage memory layout optimization, to remove the storage overhead of Option<Entity>. This could be done by changing either id or generation to a NonZeroU32. I'd propose that generation should be the one considered for the change, as it has less public API surface.

What alternative(s) have you considered?

  • Use raw entity IDs without the generation and accept the risk of reused ids.
  • Take the bit representation of Entity, increment it for storage as an wrapped NonZeroU64 and then decrement it to convert it back.
  • Accept the overhead of the Option
  • Use less sparse/flat/smarter representations for relational data (ie. chunks)

Additional context

In my particular case, I have "TileCoord" component and a "MultiTileCoord" component that create a relation between entities and a particular grid square. On top of that, I maintain a fixed-size grid structure that is updated as TileCoords are altered to accelerate neighbourhood queries and generate certain events (ie. neighbour changed, tile moved ontop). As a result, some of the grid squares would be empty which can't be represented with Entity alone, so I need to utilize Option<Entity> and incur the storage overhead.

On an example 1-layer grid of 256x256, this is an overhead of about ~256KiB. This isn't a pressing issue in my case, since I'm currently using the 2nd alternative I outlined. I just thought it might be a nice space optimization to put into core.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-FeatureA new feature, making something new possibleC-PerformanceA change motivated by improving speed, memory usage or compile times

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions