Skip to content

Conversation

@kellemar
Copy link

While looking through the rendering code, I noticed that directional_lights and lights_with_shadow vectors in _render_scene are built up with push_back() without reserving capacity first. Since we already know the upper bound from scenario->directional_lights.size(), we can avoid the reallocations.

It's a small thing, but this runs every frame during scene rendering so it adds up.

Changes

  • Added reserve() for directional_lights before the loop
  • Added reserve() for lights_with_shadow inside the directional lights block

Both use scenario->directional_lights.size() as the capacity hint, which is the maximum number of elements either vector can have.

Reserve capacity for directional_lights and lights_with_shadow vectors
before iterating over scenario lights. This avoids potential
reallocations during the rendering loop when pushing light instances.
@kellemar kellemar requested a review from a team as a code owner December 25, 2025 02:38
@Chaosus Chaosus added this to the 4.x milestone Dec 25, 2025
Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

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

I would also move the arrays to be member arrays of the class so they can be reused across frames and we can avoid making new allocations each frame.

In general we discourage making performance PRs without any profiling numbers (https://contributing.godotengine.org/en/latest/engine/guidelines/optimization.html). However, in this case it is acceptable since this also aligns with our goal of having 0 allocations per frame.

That's why I suggest taking this a step further and actually eliminating the per-frame allocations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants