From 3d69a816cf66d023cf05a52164d3ff0c121ffa16 Mon Sep 17 00:00:00 2001 From: James Liu Date: Mon, 30 May 2022 21:16:47 +0000 Subject: [PATCH] Don't allocate for ComponentDescriptors of non-dynamic component types (#4725) # Objective Don't allocate memory for Component types known at compile-time. Save a bit of memory. ## Solution Change `ComponentDescriptor::name` from `String` to `Cow<'static, str>` to use the `&'static str` returned by `std::any::type_name`. --- crates/bevy_ecs/src/component.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index 15a3bd85d87d52..319c4185283c0a 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -10,6 +10,7 @@ use bevy_ptr::OwningPtr; use std::{ alloc::Layout, any::{Any, TypeId}, + borrow::Cow, mem::needs_drop, }; @@ -164,7 +165,7 @@ impl SparseSetIndex for ComponentId { } pub struct ComponentDescriptor { - name: String, + name: Cow<'static, str>, // SAFETY: This must remain private. It must match the statically known StorageType of the // associated rust component type if one exists. storage_type: StorageType, @@ -201,7 +202,7 @@ impl ComponentDescriptor { /// Create a new `ComponentDescriptor` for the type `T`. pub fn new() -> Self { Self { - name: std::any::type_name::().to_string(), + name: Cow::Borrowed(std::any::type_name::()), storage_type: T::Storage::STORAGE_TYPE, is_send_and_sync: true, type_id: Some(TypeId::of::()), @@ -216,13 +217,13 @@ impl ComponentDescriptor { /// - the `drop` fn must be usable on a pointer with a value of the layout `layout` /// - the component type must be safe to access from any thread (Send + Sync in rust terms) pub unsafe fn new_with_layout( - name: String, + name: impl Into>, storage_type: StorageType, layout: Layout, drop: Option unsafe fn(OwningPtr<'a>)>, ) -> Self { Self { - name, + name: name.into(), storage_type, is_send_and_sync: true, type_id: None, @@ -236,7 +237,7 @@ impl ComponentDescriptor { /// The [`StorageType`] for resources is always [`TableStorage`]. pub fn new_resource() -> Self { Self { - name: std::any::type_name::().to_string(), + name: Cow::Borrowed(std::any::type_name::()), // PERF: `SparseStorage` may actually be a more // reasonable choice as `storage_type` for resources. storage_type: StorageType::Table, @@ -249,7 +250,7 @@ impl ComponentDescriptor { fn new_non_send(storage_type: StorageType) -> Self { Self { - name: std::any::type_name::().to_string(), + name: Cow::Borrowed(std::any::type_name::()), storage_type, is_send_and_sync: false, type_id: Some(TypeId::of::()), @@ -270,7 +271,7 @@ impl ComponentDescriptor { #[inline] pub fn name(&self) -> &str { - &self.name + self.name.as_ref() } }