Skip to content

Inefficient use of Vec::push in prepare_uniform_components function #8284

@CrazyRoka

Description

@CrazyRoka

I created a stress test scenario with the Bevy engine (link) where I created 100K entities. I noticed that the prepare_uniform_components function was using 4.23% of the CPU time, and upon investigating the code, I found that the Vec3::push method was being called for each of the entities, which is not efficient.

To improve performance, I suggest copying all the objects in batches instead of pushing them one by one. Apart from that, DynamicUniformBuffer::write can be optimized as well. I am attaching my Flamegraph to this issue.

fn prepare_uniform_components<C: Component>(
mut commands: Commands,
render_device: Res<RenderDevice>,
render_queue: Res<RenderQueue>,
mut component_uniforms: ResMut<ComponentUniforms<C>>,
components: Query<(Entity, &C)>,
) where
C: ShaderType + WriteInto + Clone,
{
component_uniforms.uniforms.clear();
let entities = components
.iter()
.map(|(entity, component)| {
(
entity,
DynamicUniformIndex::<C> {
index: component_uniforms.uniforms.push(component.clone()),
marker: PhantomData,
},
)
})
.collect::<Vec<_>>();
commands.insert_or_spawn_batch(entities);
component_uniforms
.uniforms
.write_buffer(&render_device, &render_queue);
}

Screenshot from 2023-04-01 17-06-22

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-RenderingDrawing game state to the screenC-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