Skip to content

Faster compilation of bevy_diagnostic #1235

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

Merged
merged 3 commits into from
Jan 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions crates/bevy_diagnostic/src/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use bevy_utils::{Duration, HashMap, Instant, Uuid};
use std::collections::{BTreeSet, VecDeque};
use bevy_utils::{Duration, Instant, StableHashMap, Uuid};
use std::collections::VecDeque;

/// Unique identifier for a [Diagnostic]
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
Expand Down Expand Up @@ -101,13 +101,13 @@ impl Diagnostic {
/// A collection of [Diagnostic]s
#[derive(Debug, Default)]
pub struct Diagnostics {
diagnostics: HashMap<DiagnosticId, Diagnostic>,
ordered_diagnostics: BTreeSet<DiagnosticId>,
// This uses a [`StableHashMap`] to ensure that the iteration order is deterministic between
// runs when all diagnostics are inserted in the same order.
diagnostics: StableHashMap<DiagnosticId, Diagnostic>,
}

impl Diagnostics {
pub fn add(&mut self, diagnostic: Diagnostic) {
self.ordered_diagnostics.insert(diagnostic.id);
self.diagnostics.insert(diagnostic.id, diagnostic);
}

Expand All @@ -134,10 +134,4 @@ impl Diagnostics {
pub fn iter(&self) -> impl Iterator<Item = &Diagnostic> {
self.diagnostics.values()
}

pub fn ordered_iter(&self) -> impl Iterator<Item = &Diagnostic> {
self.ordered_diagnostics
.iter()
.filter_map(move |k| self.diagnostics.get(k))
}
}
4 changes: 2 additions & 2 deletions crates/bevy_diagnostic/src/log_diagnostics_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl LogDiagnosticsPlugin {
Self::log_diagnostic(diagnostic);
}
} else {
for diagnostic in diagnostics.ordered_iter() {
for diagnostic in diagnostics.iter() {
Self::log_diagnostic(diagnostic);
}
}
Expand All @@ -96,7 +96,7 @@ impl LogDiagnosticsPlugin {
debug!("{:#?}\n", diagnostic);
}
} else {
for diagnostic in diagnostics.ordered_iter() {
for diagnostic in diagnostics.iter() {
debug!("{:#?}\n", diagnostic);
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_input/src/axis.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy_utils::{AHashExt, HashMap};
use bevy_utils::HashMap;
use std::hash::Hash;

#[derive(Debug)]
Expand All @@ -12,7 +12,7 @@ where
{
fn default() -> Self {
Axis {
axis_data: HashMap::new(),
axis_data: HashMap::default(),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
use bevy_app::prelude::{EventReader, Events};
use bevy_asset::{AssetEvent, Assets};
use bevy_ecs::{Resources, World};
use bevy_utils::{AHashExt, HashSet};
use bevy_utils::HashSet;

#[derive(Default)]
pub struct TextureCopyNode {
Expand All @@ -24,7 +24,7 @@ impl Node for TextureCopyNode {
) {
let texture_events = resources.get::<Events<AssetEvent<Texture>>>().unwrap();
let textures = resources.get::<Assets<Texture>>().unwrap();
let mut copied_textures = HashSet::new();
let mut copied_textures = HashSet::default();
for event in self.texture_event_reader.iter(&texture_events) {
match event {
AssetEvent::Created { handle } | AssetEvent::Modified { handle } => {
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_text/src/font_atlas_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use bevy_math::Vec2;
use bevy_reflect::TypeUuid;
use bevy_render::texture::Texture;
use bevy_sprite::TextureAtlas;
use bevy_utils::{AHashExt, HashMap};
use bevy_utils::HashMap;

type FontSizeKey = FloatOrd;

Expand All @@ -25,7 +25,7 @@ pub struct GlyphAtlasInfo {
impl Default for FontAtlasSet {
fn default() -> Self {
FontAtlasSet {
font_atlases: HashMap::with_capacity(1),
font_atlases: HashMap::with_capacity_and_hasher(1, Default::default()),
}
}
}
Expand Down
102 changes: 29 additions & 73 deletions crates/bevy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,89 +11,45 @@ pub type BoxedFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
#[cfg(target_arch = "wasm32")]
pub type BoxedFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;

/// A hasher builder that will create a fixed hasher.
#[derive(Default)]
pub struct FixedState;

impl std::hash::BuildHasher for FixedState {
type Hasher = AHasher;

#[inline]
fn build_hasher(&self) -> AHasher {
AHasher::new_with_keys(0, 0)
}
}

/// A std hash map implementing AHash, a high speed keyed hashing algorithm
/// intended for use in in-memory hashmaps.
///
/// AHash is designed for performance and is NOT cryptographically secure.
pub type HashMap<K, V> = std::collections::HashMap<K, V, RandomState>;

pub trait AHashExt {
fn new() -> Self;

fn with_capacity(capacity: usize) -> Self;
}

impl<K, V> AHashExt for HashMap<K, V> {
/// Creates an empty `HashMap` with AHash.
///
/// The hash map is initially created with a capacity of 0, so it will not
/// allocate until it is first inserted into.
///
/// # Examples
///
/// ```
/// use bevy_utils::{HashMap, AHashExt};
/// let mut map: HashMap<&str, i32> = HashMap::new();
/// ```
#[inline]
fn new() -> Self {
Default::default()
}

/// Creates an empty `HashMap` with the specified capacity with AHash.
///
/// The hash map will be able to hold at least `capacity` elements without
/// reallocating. If `capacity` is 0, the hash map will not allocate.
///
/// # Examples
///
/// ```
/// use bevy_utils::{HashMap, AHashExt};
/// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10);
/// ```
#[inline]
fn with_capacity(capacity: usize) -> Self {
HashMap::with_capacity_and_hasher(capacity, RandomState::default())
}
}
/// A stable std hash map implementing AHash, a high speed keyed hashing algorithm
/// intended for use in in-memory hashmaps.
///
/// Unlike [`HashMap`] this has an iteration order that only depends on the order
/// of insertions and deletions and not a random source.
///
/// AHash is designed for performance and is NOT cryptographically secure.
pub type StableHashMap<K, V> = std::collections::HashMap<K, V, FixedState>;

/// A std hash set implementing AHash, a high speed keyed hashing algorithm
/// intended for use in in-memory hashmaps.
///
/// AHash is designed for performance and is NOT cryptographically secure.
pub type HashSet<K> = std::collections::HashSet<K, RandomState>;

impl<K> AHashExt for HashSet<K> {
/// Creates an empty `HashSet` with AHash.
///
/// The hash set is initially created with a capacity of 0, so it will not
/// allocate until it is first inserted into.
///
/// # Examples
///
/// ```
/// use bevy_utils::{HashSet, AHashExt};
/// let set: HashSet<i32> = HashSet::new();
/// ```
#[inline]
fn new() -> Self {
Default::default()
}

/// Creates an empty `HashSet` with the specified capacity with AHash.
///
/// The hash set will be able to hold at least `capacity` elements without
/// reallocating. If `capacity` is 0, the hash set will not allocate.
///
/// # Examples
///
/// ```
/// use bevy_utils::{HashSet, AHashExt};
/// let set: HashSet<i32> = HashSet::with_capacity(10);
/// assert!(set.capacity() >= 10);
/// ```
#[inline]
fn with_capacity(capacity: usize) -> Self {
HashSet::with_capacity_and_hasher(capacity, RandomState::default())
}
}
/// A stable std hash set implementing AHash, a high speed keyed hashing algorithm
/// intended for use in in-memory hashmaps.
///
/// Unlike [`HashSet`] this has an iteration order that only depends on the order
/// of insertions and deletions and not a random source.
///
/// AHash is designed for performance and is NOT cryptographically secure.
pub type StableHashSet<K> = std::collections::HashSet<K, FixedState>;