Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative name component used for faster comparisons #1109

Merged
merged 4 commits into from
Dec 31, 2020

Conversation

lassade
Copy link
Contributor

@lassade lassade commented Dec 20, 2020

Name is a better alternative to name entities instead of using Option<String>, because it allows for faster searches. I'm currently using this component for find entities in deep nested hierarchies in my animation system;

It works by also storing a hash along side name, then when peforming a comparison between two Names it first check if the hashes matches, if don't the strings are different and the acctual string comparision is skipped.

I'm using ahash because it's the fastest hasing algo that I know of;

@smokku
Copy link
Member

smokku commented Dec 21, 2020

A candidate for bevy_extras crate?

@lassade
Copy link
Contributor Author

lassade commented Dec 21, 2020

This could be the default way of naming entites, thats why I put it on bevy_core

crates/bevy_core/Cargo.toml Outdated Show resolved Hide resolved
@memoryruins memoryruins added the A-ECS Entities, components, systems, and events label Dec 22, 2020
#[reflect(Component)]
pub struct Name {
hash: u64, // TODO: Shouldn't be serialized
name: String,
Copy link
Member

Choose a reason for hiding this comment

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

Could this be std::borrow::Cow<'static, str>, or could this whole struct be more general then use:

type Name = FastCompare<String>;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it could

Copy link
Member

Choose a reason for hiding this comment

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

Im cool with making this less general for now to cut down on the amount of abstraction. If we find multiple use cases later and it seems worth it, we can always factor this out.

@cart
Copy link
Member

cart commented Dec 24, 2020

Can you think of a reason not to just extend the existing Labels system to cache hashes for faster comparisons?

@lassade
Copy link
Contributor Author

lassade commented Dec 26, 2020

No other that a name must be one per entity; We could so something similar to Labels but I'm not sure how that will look like;


impl Hash for Name {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It will be correct to use self.hash.hash(state)?

Copy link
Member

Choose a reason for hiding this comment

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

I think we could probably get away with that. Its effectively double-hashing, so our collision risk almost certainly goes up.

But short of implementing a custom hasher for every Name use case, im not sure we have a better option.

Copy link
Member

Choose a reason for hiding this comment

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

Eh actually I'd rather be safe now and optimize later if we prove its not too risky.

@cart
Copy link
Member

cart commented Dec 26, 2020

I do think this is probably a good candidate for a bevy_extra crate. I'm not yet convinced we need "canonical names" built in to the engine by default. "selecting by string name" isn't a general pattern we should be encouraging (we should encourage marker components), and the cases where it makes sense are very context specific (and therefore should probably live in game code). Even the Labels system we currently have should probably live in bevy_extra (at least for now). I added them for some debugging scenarios and because Godot has a similar feature, but i think the Labels system will only really start getting useful in the context of a visual scene editor.

I think its time to get bevy_extra rolling. It would be a separate repo (to draw hard lines between the projects and denote a different level of support).

@mockersf
Copy link
Member

to add context on why Name (or Labels) can be useful as a fully supported component, as I had the "need" for them:

  • when loading a gltf file, names can be specified from the file, and a marker component can't be generated for them. this is related to the scene need you mention
  • @lassade is working on animations, where one can specify the target for an animation by a path made of names

@cart
Copy link
Member

cart commented Dec 26, 2020

Yeah thats fair. And I guess canonical names are good for visual scene organization (ex the identifier used when rendering entity hierarchies in the editor).

In general I have a reflex to not add something like this until we have a concrete scenario that uses it. But I guess it probably makes sense for GLTF-loaded entities to use the GLTF node name as the "canonical name displayed in the bevy editor hierarchy viewer".

Ok I think im convinced that we should have this in-engine.

@cart cart merged commit 30fd302 into bevyengine:master Dec 31, 2020
@lassade lassade deleted the alt-name branch April 5, 2021 22:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants