diff --git a/benches/benches/bevy_ecs/main.rs b/benches/benches/bevy_ecs/main.rs index 9e59d31aca..ec3447549f 100644 --- a/benches/benches/bevy_ecs/main.rs +++ b/benches/benches/bevy_ecs/main.rs @@ -15,6 +15,7 @@ mod fragmentation; mod iteration; mod observers; mod param; +mod resources; mod scheduling; mod world; @@ -28,6 +29,7 @@ criterion_main!( iteration::benches, fragmentation::benches, observers::benches, + resources::benches, scheduling::benches, world::benches, param::benches, diff --git a/benches/benches/bevy_ecs/resources.rs b/benches/benches/bevy_ecs/resources.rs new file mode 100644 index 0000000000..736e5daaee --- /dev/null +++ b/benches/benches/bevy_ecs/resources.rs @@ -0,0 +1,69 @@ +use std::{alloc::Layout, hint::black_box, ptr::NonNull}; + +use benches::bench; +use bevy_ecs::{ + change_detection::MaybeLocation, + component::{ComponentCloneBehavior, ComponentDescriptor, StorageType}, + prelude::*, + ptr::OwningPtr, +}; +use criterion::{criterion_group, Criterion}; + +criterion_group!(benches, get, get_mut, insert_remove); + +fn create_world() -> World { + let mut world = World::new(); + for _ in 0..500 { + // SAFETY: Uses zero-sized value, never drops + unsafe { + let resource_id = + world.register_component_with_descriptor(ComponentDescriptor::new_with_layout( + "", + StorageType::SparseSet, + Layout::new::<()>(), + None, + true, + ComponentCloneBehavior::Default, + None, + )); + world.insert_resource_by_id( + resource_id, + OwningPtr::new(NonNull::dangling()), + MaybeLocation::caller(), + ); + } + } + world +} + +#[derive(Resource)] +struct R; + +pub fn get(criterion: &mut Criterion) { + let mut world = create_world(); + world.insert_resource(R); + criterion.bench_function(bench!("get"), |bencher| { + bencher.iter(|| world.get_resource::()); + }); +} + +pub fn get_mut(criterion: &mut Criterion) { + let mut world = create_world(); + world.insert_resource(R); + criterion.bench_function(bench!("get_mut"), |bencher| { + bencher.iter(|| { + black_box(world.get_resource_mut::()); + }); + }); +} + +pub fn insert_remove(criterion: &mut Criterion) { + let mut world = create_world(); + criterion.bench_function(bench!("insert_remove"), |bencher| { + bencher.iter(|| { + world.insert_resource(R); + black_box(&mut world); + world.remove_resource::() + }); + }); +} diff --git a/crates/bevy_ecs/macros/src/resource.rs b/crates/bevy_ecs/macros/src/resource.rs index 439aeb8a96..406c24e3b3 100644 --- a/crates/bevy_ecs/macros/src/resource.rs +++ b/crates/bevy_ecs/macros/src/resource.rs @@ -1,4 +1,4 @@ -use bevy_ecs_macro_logic::component::DeriveComponent; +use bevy_ecs_macro_logic::component::{DeriveComponent, StorageTy}; use bevy_macro_utils::fq_std::FQOption; use proc_macro2::TokenStream; use quote::quote; @@ -10,6 +10,7 @@ pub fn derive_resource(ast: &mut DeriveInput) -> TokenStream { Ok(value) => value, Err(e) => return e.into_compile_error(), }; + derive_component.storage = StorageTy::SparseSet; let struct_name = &ast.ident; let (_, type_generics, _) = &ast.generics.split_for_impl();