From 8898c9e14221a5e5ed05005927bfc5b185753dab Mon Sep 17 00:00:00 2001 From: Rob Parrett Date: Sun, 5 Jan 2025 12:28:11 -0800 Subject: [PATCH] Use `radsort` for sprite picking (#17174) # Objective Optimization for sprite picking ## Solution Use `radsort` for the sort. We already have `radsort` in tree for sorting various phase items (including `Transparent2d` / sprites). It's a stable parallel radix sort. ## Testing Tested on an M1 Max. `cargo run --example sprite_picking` `cargo run --example bevymark --release --features=trace,trace_tracy -- --waves 100 --per-wave 1000 --benchmark` image --- crates/bevy_sprite/src/picking_backend.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/bevy_sprite/src/picking_backend.rs b/crates/bevy_sprite/src/picking_backend.rs index 4202939e24..5d1e652db3 100644 --- a/crates/bevy_sprite/src/picking_backend.rs +++ b/crates/bevy_sprite/src/picking_backend.rs @@ -2,15 +2,13 @@ //! sprites with arbitrary transforms. Picking is done based on sprite bounds, not visible pixels. //! This means a partially transparent sprite is pickable even in its transparent areas. -use core::cmp::Reverse; - use crate::{Sprite, TextureAtlasLayout}; use bevy_app::prelude::*; use bevy_asset::prelude::*; use bevy_color::Alpha; use bevy_ecs::prelude::*; use bevy_image::Image; -use bevy_math::{prelude::*, FloatExt, FloatOrd}; +use bevy_math::{prelude::*, FloatExt}; use bevy_picking::backend::prelude::*; use bevy_reflect::prelude::*; use bevy_render::prelude::*; @@ -83,7 +81,11 @@ fn sprite_picking( } }) .collect(); - sorted_sprites.sort_by_key(|x| Reverse(FloatOrd(x.2.translation().z))); + + // radsort is a stable radix sort that performed better than `slice::sort_by_key` + radsort::sort_by_key(&mut sorted_sprites, |(_, _, transform, _)| { + -transform.translation().z + }); let primary_window = primary_window.get_single().ok();