From 59b804335a0d1969ffaaba0259873444dee3fea4 Mon Sep 17 00:00:00 2001 From: kennethloeffler Date: Tue, 29 Oct 2024 19:39:49 +0000 Subject: [PATCH 1/2] Don't create queue in WeakDom::insert for instances with no children --- rbx_dom_weak/src/dom.rs | 44 +++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/rbx_dom_weak/src/dom.rs b/rbx_dom_weak/src/dom.rs index 0d5ae8c22..c57f8ee27 100644 --- a/rbx_dom_weak/src/dom.rs +++ b/rbx_dom_weak/src/dom.rs @@ -109,16 +109,13 @@ impl WeakDom { /// ## Panics /// Panics if `parent_ref` is some and does not refer to an instance in the DOM. pub fn insert(&mut self, parent_ref: Ref, root_builder: InstanceBuilder) -> Ref { - let root_referent = root_builder.referent; - - // Rather than performing this movement recursively, we instead use a - // queue that we load the children of each `InstanceBuilder` into. - // Then we can just iter through that. - let mut queue = VecDeque::with_capacity(1); - queue.push_back((parent_ref, root_builder)); - - while let Some((parent, builder)) = queue.pop_front() { - self.inner_insert( + fn insert( + dom: &mut WeakDom, + builder: InstanceBuilder, + parent: Ref, + queue: Option<&mut VecDeque<(Ref, InstanceBuilder)>>, + ) { + dom.inner_insert( builder.referent, Instance { referent: builder.referent, @@ -131,15 +128,36 @@ impl WeakDom { ); if parent.is_some() { - self.instances + dom.instances .get_mut(&parent) .unwrap_or_else(|| panic!("cannot insert into parent that does not exist")) .children .push(builder.referent); } - for child in builder.children { - queue.push_back((builder.referent, child)); + if let Some(queue) = queue { + for child in builder.children { + queue.push_back((builder.referent, child)); + } + } + } + + let root_referent = root_builder.referent; + + // Fast path: if the builder does not have any children, then we don't have to + // construct a queue to keep track of descendants for insertion, avoiding a heap + // allocation. + if root_builder.children.len() == 0 { + insert(self, root_builder, parent_ref, None); + } else { + // Rather than performing this movement recursively, we instead use a + // queue that we load the children of each `InstanceBuilder` into. + // Then we can just iter through that. + let mut queue = VecDeque::with_capacity(1); + queue.push_back((parent_ref, root_builder)); + + while let Some((parent, builder)) = queue.pop_front() { + insert(self, builder, parent, Some(&mut queue)); } } From 5a46fb7c37c1e3b61c26c26ccbd818ba148394d3 Mon Sep 17 00:00:00 2001 From: kennethloeffler Date: Tue, 29 Oct 2024 19:55:38 +0000 Subject: [PATCH 2/2] Nice --- rbx_dom_weak/src/dom.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rbx_dom_weak/src/dom.rs b/rbx_dom_weak/src/dom.rs index c57f8ee27..3b43ea3f0 100644 --- a/rbx_dom_weak/src/dom.rs +++ b/rbx_dom_weak/src/dom.rs @@ -147,7 +147,7 @@ impl WeakDom { // Fast path: if the builder does not have any children, then we don't have to // construct a queue to keep track of descendants for insertion, avoiding a heap // allocation. - if root_builder.children.len() == 0 { + if root_builder.children.is_empty() { insert(self, root_builder, parent_ref, None); } else { // Rather than performing this movement recursively, we instead use a