I am starting to compare the performance of my BTreeMap implementation with the std implementation, and I have this puzzle.
C:\Users\ano31\Rust\btree>cargo test std_insert_fwd --release
Locking 1 package
Updating btree_experiment v0.1.64 (C:\Users\ano31\Rust\btree) -> v0.1.65
Compiling btree_experiment v0.1.65 (C:\Users\ano31\Rust\btree)
Finished `release` profile [optimized] target(s) in 8.45s
Running unittests src\lib.rs (target\release\deps\btree_experiment-64d4677be5c2d34a.exe)
running 1 test
test test_std_insert_fwd ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 50 filtered out; finished in 1.18s
C:\Users\ano31\Rust\btree>cargo test std_insert_rev --release
Finished `release` profile [optimized] target(s) in 0.02s
Running unittests src\lib.rs (target\release\deps\btree_experiment-64d4677be5c2d34a.exe)
running 1 test
test test_std_insert_rev ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 50 filtered out; finished in 0.88s
So inserting in ascending order took 1.18s, but descending order only took 0.88 ( these results are quite consistent ).
These are the tests:
#[test]
fn test_std_insert_fwd() {
for _rep in 0..1000 {
let mut t = std::collections::BTreeMap::<usize, usize>::default();
let n = 10000;
for i in 0..n {
t.insert(i, i);
}
}
}
and
#[test]
fn test_std_insert_rev() {
for _rep in 0..1000 {
let mut t = std::collections::BTreeMap::<usize, usize>::default();
let n = 10000;
for i in (0..n).rev() {
t.insert(i, i);
}
}
}
Now I would expect inserting in ascending order to be (slightly) faster, as when inserting into the underlying Vec, there is no need to move the existing elements up, and in my implementation this is indeed the case. So why is std slower?
[ Another thing I just realised (if I am not mistaken), the std implementation stores raw pointers to parent nodes, which is interesting. It means a lot of unsafe code. It is quite a lot of modules, and I only just started looking at the code, here:
]