diff options
| author | HampusM <hampus@hampusmat.com> | 2024-12-22 13:08:18 +0100 | 
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2024-12-22 13:08:18 +0100 | 
| commit | b2347c240a8bc69adca13288a2fd8ca1e5eccce5 (patch) | |
| tree | 2cd5615a3b0317928dffdf3ce60b2dcfb50dee4c /ecs/src | |
| parent | 098a2a44465b2062f1de1afc242aa1852f9d95a5 (diff) | |
perf(ecs): make archetype index by ID lookup faster
Diffstat (limited to 'ecs/src')
| -rw-r--r-- | ecs/src/component/storage.rs | 73 | 
1 files changed, 40 insertions, 33 deletions
| diff --git a/ecs/src/component/storage.rs b/ecs/src/component/storage.rs index 5098c5f..53b1168 100644 --- a/ecs/src/component/storage.rs +++ b/ecs/src/component/storage.rs @@ -53,8 +53,7 @@ impl Storage      {          let archetype_id = self.entity_archetype_lookup.get(&entity_uid)?; -        let archetype_index = -            self.find_archetype_index_with_entity(*archetype_id, entity_uid)?; +        let archetype_index = self.get_archetype_index_by_id(*archetype_id)?;          self.archetypes.get(archetype_index)      } @@ -65,9 +64,7 @@ impl Storage              return;          }; -        let Some(archetype_index) = -            self.find_archetype_index_with_entity(*archetype_id, entity_uid) -        else { +        let Some(archetype_index) = self.get_archetype_index_by_id(*archetype_id) else {              return;          }; @@ -148,8 +145,7 @@ impl Storage      {          let archetype_id = self.entity_archetype_lookup.get(&entity_uid)?; -        let archetype_index = -            self.find_archetype_index_with_entity(*archetype_id, entity_uid)?; +        let archetype_index = self.get_archetype_index_by_id(*archetype_id)?;          let archetype = self.archetypes.get_mut(archetype_index)?; @@ -200,8 +196,7 @@ impl Storage      {          let archetype_id = self.entity_archetype_lookup.get(&entity_uid)?; -        let archetype_index = -            self.find_archetype_index_with_entity(*archetype_id, entity_uid)?; +        let archetype_index = self.get_archetype_index_by_id(*archetype_id)?;          let archetype = self.archetypes.get_mut(archetype_index)?; @@ -280,29 +275,24 @@ impl Storage          unsafe { *lookup_entry.archetype_indices.first().unwrap_unchecked() }      } -    fn find_archetype_index_with_entity( -        &self, -        archetype_id: ArchetypeId, -        entity_uid: Uid, -    ) -> Option<usize> +    fn get_archetype_index_by_id(&self, archetype_id: ArchetypeId) -> Option<usize>      { -        let archetype_lookup = self.archetype_lookup.borrow_mut(); +        let archetype_lookup = self.archetype_lookup.borrow();          let archetype_lookup_entry = archetype_lookup.get(&archetype_id)?; -        // TODO: Also have a hashmap for precise archetype ID -> archetype index lookup. -        // This way is slow -        archetype_lookup_entry +        let index = *archetype_lookup_entry              .archetype_indices -            .iter() -            .find(|archetype_index| { -                let Some(archetype) = self.archetypes.get(**archetype_index) else { -                    return false; -                }; +            .first() +            .expect("No archetype indices in archetype lookup entry"); -                archetype.has_entity(entity_uid) -            }) -            .copied() +        debug_assert!( +            self.archetypes.get(index).is_some_and(|archetype| archetype +                .component_ids_is(&archetype_lookup_entry.component_ids)), +            "Archetype components is not exact match" +        ); + +        Some(index)      }      fn iter_archetypes_by_lookup(&self, archetype_id: ArchetypeId) @@ -334,24 +324,35 @@ impl Storage      {          let comp_ids_set = create_non_opt_component_id_set(comp_metadata_list.as_ref()); +        let mut exact_matching_archetype_index = None; +          let matching_archetype_indices = self              .archetypes              .iter()              .enumerate()              .filter_map(|(index, archetype)| { +                if archetype.component_ids_is(&comp_ids_set) { +                    exact_matching_archetype_index = Some(index); + +                    return None; +                } +                  if archetype.component_ids_is_superset(&comp_ids_set) {                      return Some(index);                  }                  None              }) -            .collect(); +            .collect::<Vec<_>>();          self.archetype_lookup.borrow_mut().insert(              archetype_id,              ArchetypeLookupEntry {                  component_ids: comp_ids_set, -                archetype_indices: matching_archetype_indices, +                archetype_indices: exact_matching_archetype_index +                    .into_iter() +                    .chain(matching_archetype_indices) +                    .collect(),              },          );      } @@ -414,6 +415,17 @@ impl Archetype          }      } +    pub fn component_ids_is(&self, other_component_ids: &HashSet<Uid>) -> bool +    { +        if other_component_ids.len() == self.component_ids.len() { +            other_component_ids +                .iter() +                .all(|v| self.component_ids.contains_key(v)) +        } else { +            false +        } +    } +      pub fn get_entity(&self, entity_uid: Uid) -> Option<&ArchetypeEntity>      {          let entity_index = *self.entity_lookup.get(&entity_uid)?; @@ -462,11 +474,6 @@ impl Archetype          Some(entity)      } - -    fn has_entity(&self, entity_uid: Uid) -> bool -    { -        self.entity_lookup.contains_key(&entity_uid) -    }  }  #[derive(Debug)] | 
