From 72a6a14f19aa9f46ca07fc8fe328a556606d0e4c Mon Sep 17 00:00:00 2001 From: Nathan Ward Date: Wed, 19 May 2021 18:41:46 +0000 Subject: [PATCH] Optimize Events::extend and impl std::iter::Extend (#2207) The previous implementation of `Events::extend` iterated through each event and manually `sent` it via `Events:;send`. However, this could be a minor performance hit since calling `Vec::push` in a loop is not optimal. This refactors the code to use `Vec::extend`. --- crates/bevy_ecs/src/event.rs | 51 +++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/crates/bevy_ecs/src/event.rs b/crates/bevy_ecs/src/event.rs index 36113eb39dde4..975afcf164b89 100644 --- a/crates/bevy_ecs/src/event.rs +++ b/crates/bevy_ecs/src/event.rs @@ -277,7 +277,7 @@ impl Events { id: self.event_count, _marker: PhantomData, }; - trace!("Events::send() -> {}", event_id); + trace!("Events::send() -> id: {}", event_id); let event_instance = EventInstance { event_id, event }; @@ -361,15 +361,6 @@ impl Events { } } - pub fn extend(&mut self, events: I) - where - I: Iterator, - { - for event in events { - self.send(event); - } - } - /// Iterates over events that happened since the last "update" call. /// WARNING: You probably don't want to use this call. In most cases you should use an /// `EventReader`. You should only use this if you know you only need to consume events @@ -384,6 +375,35 @@ impl Events { } } +impl std::iter::Extend for Events { + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + let mut event_count = self.event_count; + let events = iter.into_iter().map(|event| { + let event_id = EventId { + id: event_count, + _marker: PhantomData, + }; + event_count += 1; + EventInstance { event_id, event } + }); + + match self.state { + State::A => self.events_a.extend(events), + State::B => self.events_b.extend(events), + } + + trace!( + "Events::extend() -> ids: ({}..{})", + self.event_count, + event_count + ); + self.event_count = event_count; + } +} + #[cfg(test)] mod tests { use super::*; @@ -526,4 +546,15 @@ mod tests { assert!(events.drain().eq(vec![E(0), E(1)].into_iter())); }); } + + #[test] + fn test_events_extend_impl() { + let mut events = Events::::default(); + let mut reader = events.get_reader(); + + events.extend(vec![TestEvent { i: 0 }, TestEvent { i: 1 }]); + assert!(reader + .iter(&events) + .eq([TestEvent { i: 0 }, TestEvent { i: 1 }].iter())); + } }