on master help sign in
Diff nodes by reference rather than by value

This avoids a bunch of memcpy'ing since node isn't a tiny structure.

commit3906f80fad03b58cf7a2626ad5d0f2f5cbc30fa0 authorNick Fitzgerald <fitzgen@gmail.com> dateThu 11 Apr 2019, 13:43 (8 years ago) parent649bef1
3 files changed+41−30
src/cached_set.rs+2−2 src/diff.rs+37−26 src/vdom.rs+2−2
src/cached_set.rs+2−2
@@ -140,7 +140,7 @@ impl CachedSet {
140140 }
141141
142142 /// Get the node for the given cache id.
143− pub fn get(&self, mut id: CacheId) -> Node {
143+ pub fn get(&self, mut id: CacheId) -> &Node {
144144 debug!("CachedSet::get: id = {:?}", id);
145145 loop {
146146 let entry = self
@@ -152,7 +152,7 @@ impl CachedSet {
152152 id = c.id;
153153 continue;
154154 } else {
155− return node.clone();
155+ return node;
156156 }
157157 }
158158 }
src/diff.rs+37−26
@@ -11,8 +11,8 @@ pub(crate) fn diff(
1111 cached_set: &CachedSet,
1212 change_list: &mut ChangeListBuilder,
1313 registry: &mut EventsRegistry,
14− old: Node,
15− new: Node,
14+ old: &Node,
15+ new: &Node,
1616 cached_roots: &mut FxHashSet<CacheId>,
1717) {
1818 match (&new.kind, &old.kind) {
@@ -197,6 +197,11 @@ fn diff_children(
197197 return;
198198 }
199199
200+ if old.is_empty() {
201+ create_children(cached_set, change_list, registry, new, cached_roots);
202+ return;
203+ }
204+
200205 debug!(" updating children shared by old and new");
201206
202207 let num_children_to_diff = cmp::min(new.len(), old.len());
@@ -222,8 +227,8 @@ fn diff_children(
222227 cached_set,
223228 change_list,
224229 registry,
225− old_child.clone(),
226− new_child.clone(),
230+ old_child,
231+ new_child,
227232 cached_roots,
228233 );
229234 }
@@ -240,20 +245,17 @@ fn diff_children(
240245 pushed = false;
241246 } else {
242247 debug!(" creating new children");
243− for (i, new_child) in new_children.enumerate() {
244− if i == 0 && pushed {
245− change_list.pop();
246− pushed = false;
247− }
248− create(
249− cached_set,
250− change_list,
251− registry,
252− new_child.clone(),
253− cached_roots,
254− );
255− change_list.append_child();
248+ if pushed {
249+ change_list.pop();
250+ pushed = false;
256251 }
252+ create_children(
253+ cached_set,
254+ change_list,
255+ registry,
256+ new_children,
257+ cached_roots,
258+ );
257259 }
258260
259261 debug!(" done updating children");
@@ -262,6 +264,21 @@ fn diff_children(
262264 }
263265}
264266
267+fn create_children<'a, I>(
268+ cached_set: &CachedSet,
269+ change_list: &mut ChangeListBuilder,
270+ registry: &mut EventsRegistry,
271+ new: I,
272+ cached_roots: &mut FxHashSet<CacheId>,
273+) where
274+ I: IntoIterator<Item = &'a Node<'a>>,
275+{
276+ for child in new {
277+ create(cached_set, change_list, registry, child, cached_roots);
278+ change_list.append_child();
279+ }
280+}
281+
265282fn remove_children(
266283 change_list: &mut ChangeListBuilder,
267284 registry: &mut EventsRegistry,
@@ -279,7 +296,7 @@ fn create(
279296 cached_set: &CachedSet,
280297 change_list: &mut ChangeListBuilder,
281298 registry: &mut EventsRegistry,
282− node: Node,
299+ node: &Node,
283300 cached_roots: &mut FxHashSet<CacheId>,
284301) {
285302 match node.kind {
@@ -308,17 +325,11 @@ fn create(
308325 change_list.set_attribute(&attr.name, &attr.value);
309326 }
310327 for child in children {
311− create(
312− cached_set,
313− change_list,
314− registry,
315− child.clone(),
316− cached_roots,
317− );
328+ create(cached_set, change_list, registry, child, cached_roots);
318329 change_list.append_child();
319330 }
320331 }
321− NodeKind::Cached(c) => {
332+ NodeKind::Cached(ref c) => {
322333 cached_roots.insert(c.id);
323334 let node = cached_set.get(c.id);
324335 create(cached_set, change_list, registry, node, cached_roots)
src/vdom.rs+2−2
@@ -277,8 +277,8 @@ impl VdomInnerExclusive {
277277 &cached_set,
278278 &mut change_list,
279279 &mut registry,
280− old_contents,
281− new_contents.clone(),
280+ &old_contents,
281+ &new_contents,
282282 &mut cache_roots,
283283 );
284284