From 1d98eee6dea9e679f8c950df4c5b6e176584b65a Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Sun, 19 Apr 2026 16:29:02 +0200 Subject: [PATCH] perf(widget): avoid VecDeque clone in segmented_button/table Model::clear MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Model::clear() cloned the entire order VecDeque to iterate while remove() mutated it, producing an O(n) allocation proportional to the number of items — needless on a clear() which is going to drop all of them anyway. Replace the clone with std::mem::take(&mut self.order): we iterate the taken VecDeque (transferring ownership), and the inner self.order.remove(index) in each remove() call now finds position()==None and no-ops, since self.order has been swapped with an empty default. Same semantics, zero allocation. Noticeable on large nav/table models (>100 items) and on apps that reset state frequently (settings pages, file lists, context menus). --- src/widget/segmented_button/model/mod.rs | 5 ++++- src/widget/table/model/mod.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/widget/segmented_button/model/mod.rs b/src/widget/segmented_button/model/mod.rs index e0dd8c5..fff1cf6 100644 --- a/src/widget/segmented_button/model/mod.rs +++ b/src/widget/segmented_button/model/mod.rs @@ -132,7 +132,10 @@ where /// ``` #[inline] pub fn clear(&mut self) { - for entity in self.order.clone() { + // `remove()` mutates `self.order`, so transfer ownership first: + // the inner `self.order.remove(index)` then no-ops because + // `position()` can't find the entity in the empty VecDeque. + for entity in std::mem::take(&mut self.order) { self.remove(entity); } } diff --git a/src/widget/table/model/mod.rs b/src/widget/table/model/mod.rs index d6250ea..749860f 100644 --- a/src/widget/table/model/mod.rs +++ b/src/widget/table/model/mod.rs @@ -100,7 +100,10 @@ where /// model.clear(); /// ``` pub fn clear(&mut self) { - for entity in self.order.clone() { + // `remove()` mutates `self.order`, so transfer ownership first: + // the inner `self.order.remove(index)` then no-ops because + // `position()` can't find the entity in the empty VecDeque. + for entity in std::mem::take(&mut self.order) { self.remove(entity); } }