From ce7bd6955f85baf53b3e1091974be70c6cf88b49 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Tue, 21 Mar 2023 13:25:49 +0100 Subject: [PATCH] perf(pubsub): Skip clone on last message --- embassy-sync/src/pubsub/mod.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/embassy-sync/src/pubsub/mod.rs b/embassy-sync/src/pubsub/mod.rs index 5989e86ec..59e701c58 100644 --- a/embassy-sync/src/pubsub/mod.rs +++ b/embassy-sync/src/pubsub/mod.rs @@ -322,12 +322,15 @@ impl PubSubSta // We're reading this item, so decrement the counter queue_item.1 -= 1; - let message = queue_item.0.clone(); - if current_message_index == 0 && queue_item.1 == 0 { - self.queue.pop_front(); + let message = if current_message_index == 0 && queue_item.1 == 0 { + let (message, _) = self.queue.pop_front().unwrap(); self.publisher_wakers.wake(); - } + // Return pop'd message without clone + message + } else { + queue_item.0.clone() + }; Some(WaitResult::Message(message)) } @@ -659,4 +662,25 @@ mod tests { assert_eq!(4, channel.space()); } + + struct CloneCallCounter(usize); + + impl Clone for CloneCallCounter { + fn clone(&self) -> Self { + Self(self.0 + 1) + } + } + + #[futures_test::test] + async fn skip_clone_for_last_message() { + let channel = PubSubChannel::::new(); + let pub0 = channel.publisher().unwrap(); + let mut sub0 = channel.subscriber().unwrap(); + let mut sub1 = channel.subscriber().unwrap(); + + pub0.publish(CloneCallCounter(0)).await; + + assert_eq!(1, sub0.try_next_message_pure().unwrap().0); + assert_eq!(0, sub1.try_next_message_pure().unwrap().0); + } }