diff --git a/crates/bevy_ecs/Cargo.toml b/crates/bevy_ecs/Cargo.toml index e1355f3ca9..cbeade0b59 100644 --- a/crates/bevy_ecs/Cargo.toml +++ b/crates/bevy_ecs/Cargo.toml @@ -20,6 +20,7 @@ trace = [] bevy_tasks = { path = "../bevy_tasks", version = "0.4.0" } bevy_utils = { path = "../bevy_utils", version = "0.4.0" } bevy_ecs_macros = { path = "macros", version = "0.4.0" } +fxhash = "0.2" rand = "0.7.3" serde = "1.0" thiserror = "1.0" diff --git a/crates/bevy_ecs/src/core/archetype.rs b/crates/bevy_ecs/src/core/archetype.rs index bd3763ad6e..cc10e9d42a 100644 --- a/crates/bevy_ecs/src/core/archetype.rs +++ b/crates/bevy_ecs/src/core/archetype.rs @@ -15,14 +15,12 @@ // modified by Bevy contributors use crate::{AtomicBorrow, Component, Entity}; -use bevy_utils::AHasher; use bitflags::bitflags; use std::{ alloc::{alloc, dealloc, Layout}, any::{type_name, TypeId}, cell::UnsafeCell, collections::HashMap, - hash::{BuildHasherDefault, Hasher}, mem, ptr::{self, NonNull}, }; @@ -557,44 +555,8 @@ fn align(x: usize, alignment: usize) -> usize { /// A hasher optimized for hashing a single TypeId. /// -/// TypeId is already thoroughly hashed, so there's no reason to hash it again. -/// Just leave the bits unchanged. -#[derive(Default)] -pub(crate) struct TypeIdHasher { - hash: u64, -} - -impl Hasher for TypeIdHasher { - fn write_u64(&mut self, n: u64) { - // Only a single value can be hashed, so the old hash should be zero. - debug_assert_eq!(self.hash, 0); - self.hash = n; - } - - // Tolerate TypeId being either u64 or u128. - fn write_u128(&mut self, n: u128) { - debug_assert_eq!(self.hash, 0); - self.hash = n as u64; - } - - fn write(&mut self, bytes: &[u8]) { - debug_assert_eq!(self.hash, 0); - - // This will only be called if TypeId is neither u64 nor u128, which is not anticipated. - // In that case we'll just fall back to using a different hash implementation. - let mut hasher = AHasher::default(); - hasher.write(bytes); - self.hash = hasher.finish(); - } - - fn finish(&self) -> u64 { - self.hash - } -} - -/// A HashMap with TypeId keys -/// -/// Because TypeId is already a fully-hashed u64 (including data in the high seven bits, -/// which hashbrown needs), there is no need to hash it again. Instead, this uses the much -/// faster no-op hash. -pub(crate) type TypeIdMap = HashMap>; +/// We don't use RandomState from std or Random state from Ahash +/// because fxhash is [proved to be faster](https://github.com/bevyengine/bevy/pull/1119#issuecomment-751361215) +/// and we don't need Hash Dos attack protection here +/// since TypeIds generated during compilation and there is no reason to user attack himself. +pub(crate) type TypeIdMap = HashMap;