Skip to content

Speedup resource lookup in Res and ResMut#23174

Open
Trashtalk217 wants to merge 4 commits intobevyengine:mainfrom
Trashtalk217:speedup-resource-lookup
Open

Speedup resource lookup in Res and ResMut#23174
Trashtalk217 wants to merge 4 commits intobevyengine:mainfrom
Trashtalk217:speedup-resource-lookup

Conversation

@Trashtalk217
Copy link
Contributor

Objective

See #23039. Resources as components introduced an extra entity lookup for each resource access.

Solution

Store the resource entity in the system param state of Res and ResMut. This is possible because resource entities are stable, so the state doesn't have to be updated.

Benchmarking

I quickly ran

cargo run --release --example bevymark -- --waves 60 --per-wave 500 --benchmark --mode mesh2d

and got a frametime of 33.4 ms (on main 34.6 ms). This is a minor reduction, but it might help. Others should double-check that this isn't a fluke, because my benchmarking isn't the most airtight.

Testing

All tests pass.

@alice-i-cecile alice-i-cecile added this to the 0.19 milestone Feb 28, 2026
@alice-i-cecile alice-i-cecile requested a review from hymm February 28, 2026 23:28
@github-actions
Copy link
Contributor

Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke!
You can review it at https://pixel-eagle.com/project/B04F67C0-C054-4A6F-92EC-F599FEC2FD1D?filter=PR-23174

If it's expected, please add the M-Deliberate-Rendering-Change label.

If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it.

@github-actions
Copy link
Contributor

Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke!
You can review it at https://pixel-eagle.com/project/B04F67C0-C054-4A6F-92EC-F599FEC2FD1D?filter=PR-23174

If it's expected, please add the M-Deliberate-Rendering-Change label.

If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it.

1 similar comment
@github-actions
Copy link
Contributor

Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke!
You can review it at https://pixel-eagle.com/project/B04F67C0-C054-4A6F-92EC-F599FEC2FD1D?filter=PR-23174

If it's expected, please add the M-Deliberate-Rendering-Change label.

If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it.

@Trashtalk217 Trashtalk217 added A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Feb 28, 2026
@github-project-automation github-project-automation bot moved this to Needs SME Triage in ECS Feb 28, 2026
#[inline]
unsafe fn validate_param(
&mut component_id: &mut Self::State,
&mut (component_id, entity): &mut Self::State,
Copy link
Member

@cart cart Feb 28, 2026

Choose a reason for hiding this comment

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

The redundant work in validate_param, which is done immediately before get_param never felt great to me. This isn't a problem exclusive to Res/ResMut, but it is certainly present.

I think doing validation as part of get_param is more defensible from a performance perspective.

I think it is worth doing some benchmarks where we skip validation (as-in, across all SystemParams), just to see what price we're paying here.

@SkiFire13
Copy link
Contributor

This is possible because resource entities are stable, so the state doesn't have to be updated.

This is not true:

#[test]
fn resource_component_stable() {
    #[derive(Resource)]
    struct Foo;

    let mut world = World::new();

    let component_id = world.register_component::<Foo>();

    world.insert_resource(Foo);

    let res_id1 = world.resource_entities().get(component_id).copied();

    world.remove_resource_by_id(component_id);
    world.insert_resource(Foo);

    let res_id2 = world.resource_entities().get(component_id).copied();

    assert_eq!(res_id1, res_id2); // Currently fails
}

If resource entities are meant to be stable then:

  • we should have tests that check this is the case
  • there should be documentation/comments in all places that might break this invariant to ensure future changes don't mistakingly break it
  • I would also argue that ResourceEntities should not expose a remove method

@hymm
Copy link
Contributor

hymm commented Mar 2, 2026

This is a decent perf improvement. I get about 0.4ms back of the 1.4ms I lost.

image

Though we probably need to figure out how to actually make the entities stable without any loopholes before we merge this.

@alice-i-cecile
Copy link
Member

Though we probably need to figure out how to actually make the entities stable without any loopholes before we merge this.

Or alternatively, have a way to invalidate all of these caches that does not regress perf.

@alice-i-cecile alice-i-cecile added D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Mar 2, 2026
@alice-i-cecile alice-i-cecile removed this from the 0.19 milestone Mar 3, 2026
@alice-i-cecile alice-i-cecile changed the title Speedup resource lookup in Res en ResMut Speedup resource lookup in Res and ResMut Mar 3, 2026
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-Performance A change motivated by improving speed, memory usage or compile times D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

5 participants