frol / completely-unscientific-benchmarks

Naive performance comparison of a few programming languages (JavaScript, Kotlin, Rust, Swift, Nim, Python, Go, Haskell, D, C++, Java, C#, Object Pascal, Ada, Lua, Ruby)
Apache License 2.0
547 stars 68 forks source link

Remove unnecessary .take() calls in Rust #84

Closed CryZe closed 4 years ago

CryZe commented 4 years ago

These are not necessary because the compiler can statically reason about temporary "uninitialized" variables. Unfortunately this doesn't work for self.root in the Tree methods, as there the uninitialized memory could be perceivable when those methods panic.

Looking at the assembly, this removes some unnecessary drop calls, so this should result in a slight speedup.

frol commented 4 years ago

Wow, this improved the performance noticeably! We are down from 0.315s to 0.230s!

This was not possible in Rust 1.26 (before NLL, with the old borrow checker)!

error[E0382]: use of partially moved value: `lower_node`
  --> src/idiomatic_impl.rs:31:17
   |
31 |                 lower_node.right = merge(lower_node.right, Some(greater_node));
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^----------------^^^^^^^^^^^^^^^^^^^^^
   |                 |                        |
   |                 |                        value moved here
   |                 value used here after move
   |
   = note: move occurs because `lower_node.right` has type `std::option::Option<std::boxed::Box<idiomatic_impl::Node>>`, which does not implement the `Copy` trait