Skip to content

Conversation

@ElliottjPierce
Copy link
Contributor

Objective

As per this comment on #18670, this PR attempts to make entity related benchmarks more realistic by warming up the entity allocator. This helps test the freelist in the entity allocator.

Solution

This PR introduces a new WorldBuilder type that starts with World::new, allows configuration options for warming up the world via the builder pattern, and then builds the warmed up, realistic world. For now, the only available "warm up" is for entities, but we could also add functionality in the future to cache bundle info, pre-create tables, etc to make our benchmarks more realistic. That is, more closely match the performance of a running app, rather than an app at startup.

The current implementation for entity warmups allocates some entities and frees them in a random order. It also spawns the highest allocated entity index to prepare Entities's location storage, etc. This involves using rng (deterministically), but without this, the entities are allocated in a linear index order (0, 1, 2, ...), which is unrealistic and extremely cache friendly (so it probably makes an impact in performance not desirable for a benchmark).

The major downsides here are that the benches take a little longer to run now and that startup/caching time is no longer benchmarked. That is for example, that benchmarking despawning only one entity used to tell us some information about performance of allocating the free list (amongst other one time actions). Now, that information is lost since the world is already warmed up. In practice, for N values of entities, it used to be the case that a higher N showed the performance of the operation, and a lower N showed the performance of the operation + any registration/caching costs. Now, the different N values only tell us more about how well the CPU accommodates a batch of the operation.

Currently in Bevy, making a change might make the ...1_entity benches much worse but the ...1000_entities much much better because the change added some new caching. The inverse is also common. With this PR, that will no longer be the case, at least for entities and whatever else we add to the WorldBuilder in the future. And that change may or may not be desirable.

Testing

Ran a sampling of the benchmarks.

@ElliottjPierce ElliottjPierce added A-ECS Entities, components, systems, and events C-Benchmarks Stress tests and benchmarks used to measure how fast things are D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jan 22, 2026
Copy link
Member

@cart cart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to test the "worst" / "common" real world case in these instances. Might eventually be worth adding a benchmark or two explicitly for "fresh world" spawns, but not a priority. At least on my machine this doesn't have a major impact on the results.

@cart cart added this pull request to the merge queue Jan 23, 2026
Merged via the queue into bevyengine:main with commit cf8f9be Jan 23, 2026
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ECS Entities, components, systems, and events C-Benchmarks Stress tests and benchmarks used to measure how fast things are D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants