Skip rehashing TypeIds (#11268)
# Objective `TypeId` contains a high-quality hash. Whenever a lookup based on a `TypeId` is performed (e.g. to insert/remove components), the hash is run through a second hash function. This is unnecessary. ## Solution Skip re-hashing `TypeId`s. In my [testing](https://gist.github.com/SpecificProtagonist/4b49ad74c6b82b0aedd3b4ea35121be8), this improves lookup performance consistently by 10%-15% (of course, the lookup is only a small part of e.g. a bundle insertion).
This commit is contained in:
parent
98b62e829d
commit
69760c78cf
@ -54,7 +54,30 @@ pub mod prelude {
|
|||||||
pub use bevy_utils::all_tuples;
|
pub use bevy_utils::all_tuples;
|
||||||
|
|
||||||
/// A specialized hashmap type with Key of [`TypeId`]
|
/// A specialized hashmap type with Key of [`TypeId`]
|
||||||
type TypeIdMap<V> = rustc_hash::FxHashMap<TypeId, V>;
|
type TypeIdMap<V> =
|
||||||
|
std::collections::HashMap<TypeId, V, std::hash::BuildHasherDefault<NoOpTypeIdHasher>>;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[derive(Default)]
|
||||||
|
struct NoOpTypeIdHasher(u64);
|
||||||
|
|
||||||
|
// TypeId already contains a high-quality hash, so skip re-hashing that hash.
|
||||||
|
impl std::hash::Hasher for NoOpTypeIdHasher {
|
||||||
|
fn finish(&self) -> u64 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, _bytes: &[u8]) {
|
||||||
|
// This will never be called: TypeId always just calls write_u64 once!
|
||||||
|
// This is unlikely to ever change, but as it isn't officially guaranteed,
|
||||||
|
// panicking will let us detect this as fast as possible.
|
||||||
|
unimplemented!("Hashing of std::any::TypeId changed");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_u64(&mut self, i: u64) {
|
||||||
|
self.0 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user