Skip to content

Commit b6f612c

Browse files
Yu-zhbobzhang
authored andcommitted
perf(sorted_map,sorted_set): update height before the consuming store in rotate_l/rotate_r
With #owned(n), storing n into the rotated node consumes the reference; calling n.update_height() after the store forced the compiler to keep n alive across it. Hoisting the height update (n's children are final at that point) makes the store the last use: sorted_map rotations drop from 3 incref/2 decref (borrowed baseline) to 1/1.
1 parent 18dd827 commit b6f612c

2 files changed

Lines changed: 12 additions & 4 deletions

File tree

sorted_map/map.mbt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,11 @@ fn[K, V] balance(root : Node[K, V]) -> Node[K, V] {
598598
fn[K, V] rotate_l(n : Node[K, V]) -> Node[K, V] {
599599
let r = n.right.unwrap()
600600
n.right = r.left
601-
r.left = Some(n)
601+
// Update n's height before storing it: the store consumes the owned `n`
602+
// reference, and touching `n` afterwards would force an extra
603+
// incref/decref pair to keep it alive across the store.
602604
n.update_height()
605+
r.left = Some(n)
603606
r.update_height()
604607
r
605608
}
@@ -609,8 +612,9 @@ fn[K, V] rotate_l(n : Node[K, V]) -> Node[K, V] {
609612
fn[K, V] rotate_r(n : Node[K, V]) -> Node[K, V] {
610613
let l = n.left.unwrap()
611614
n.left = l.right
612-
l.right = Some(n)
615+
// See rotate_l: keep the consuming store as the last use of `n`.
613616
n.update_height()
617+
l.right = Some(n)
614618
l.update_height()
615619
l
616620
}

sorted_set/set.mbt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,11 @@ fn[V] balance(root : Node[V]) -> Node[V] {
612612
fn[V] rotate_l(n : Node[V]) -> Node[V] {
613613
let r = n.right.unwrap()
614614
n.right = r.left
615-
r.left = Some(n)
615+
// Update n's height before storing it: the store consumes the owned `n`
616+
// reference, and touching `n` afterwards would force an extra
617+
// incref/decref pair to keep it alive across the store.
616618
n.update_height()
619+
r.left = Some(n)
617620
r.update_height()
618621
r
619622
}
@@ -623,8 +626,9 @@ fn[V] rotate_l(n : Node[V]) -> Node[V] {
623626
fn[V] rotate_r(n : Node[V]) -> Node[V] {
624627
let l = n.left.unwrap()
625628
n.left = l.right
626-
l.right = Some(n)
629+
// See rotate_l: keep the consuming store as the last use of `n`.
627630
n.update_height()
631+
l.right = Some(n)
628632
l.update_height()
629633
l
630634
}

0 commit comments

Comments
 (0)