Skip to content

Commit f9c7ba0

Browse files
committed
treemap: cut down on swap_unwrap in remove
Performance before: std::treemap::TreeMap sequential_ints 0.083971 s random_ints 0.095861 s delete_ints 0.083931 s sequential_strings 0.278272 s random_strings 0.240286 s delete_strings 0.173581 s Performance after: std::treemap::TreeMap sequential_ints 0.083297 s random_ints 0.097644 s delete_ints 0.052602 s sequential_strings 0.287326 s random_strings 0.242372 s delete_strings 0.142269 s
1 parent b0f58f6 commit f9c7ba0

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

src/libstd/treemap.rs

+21-15
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ fn insert<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: K,
626626
}
627627

628628
fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
629-
fn heir_swap<K: Ord, V>(node: &mut TreeNode<K, V>,
629+
fn heir_swap<K: Ord, V>(node: &mut ~TreeNode<K, V>,
630630
child: &mut Option<~TreeNode<K, V>>) {
631631
// *could* be done without recursion, but it won't borrow check
632632
do child.mutate |mut child| {
@@ -640,15 +640,15 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
640640
}
641641
}
642642

643-
if node.is_none() {
643+
match *node {
644+
None => {
644645
return false // bottom of tree
645-
} else {
646-
let mut save = node.swap_unwrap();
647-
648-
let removed = if save.key < *key {
649-
remove(&mut save.right, key)
646+
}
647+
Some(ref mut save) => {
648+
let (removed, this) = if save.key < *key {
649+
(remove(&mut save.right, key), false)
650650
} else if *key < save.key {
651-
remove(&mut save.left, key)
651+
(remove(&mut save.left, key), false)
652652
} else {
653653
if save.left.is_some() {
654654
if save.right.is_some() {
@@ -662,16 +662,22 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
662662
save.left = Some(left);
663663
remove(&mut save.left, key);
664664
} else {
665-
save = save.left.swap_unwrap();
665+
*save = save.left.swap_unwrap();
666666
}
667+
(true, false)
667668
} else if save.right.is_some() {
668-
save = save.right.swap_unwrap();
669+
*save = save.right.swap_unwrap();
670+
(true, false)
669671
} else {
670-
return true // leaf
672+
(true, true)
671673
}
672-
true
673674
};
674675

676+
if this {
677+
*node = None;
678+
return true;
679+
}
680+
675681
let left_level = save.left.map_default(0, |x| x.level);
676682
let right_level = save.right.map_default(0, |x| x.level);
677683

@@ -683,7 +689,7 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
683689
do save.right.mutate |mut x| { x.level = save.level; x }
684690
}
685691

686-
skew(&mut save);
692+
skew(save);
687693

688694
match save.right {
689695
Some(ref mut right) => {
@@ -696,15 +702,15 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
696702
None => ()
697703
}
698704

699-
split(&mut save);
705+
split(save);
700706
match save.right {
701707
Some(ref mut x) => { split(x) },
702708
None => ()
703709
}
704710
}
705711

706-
*node = Some(save);
707712
removed
713+
}
708714
}
709715
}
710716

0 commit comments

Comments
 (0)