I suspect we have all been tempted to experiment with unsafe optimisations, I recently thought I would have a go, and this is a report on how it went.
I decided to have a macro perf_assert! which defined as :
/// In debug mode or feature unsafe_opt not enabled, same as debug_assert! otherwise unsafe compiler hint.
#[cfg(any(debug_assertions, not(feature = "unsafe_opt")))]
macro_rules! perf_assert {
( $cond: expr ) => {
debug_assert!($cond)
};
}
/// In debug mode or feature unsafe_opt not enabled, same as debug_assert! otherwise unsafe compiler hint.
#[cfg(all(not(debug_assertions), feature = "unsafe_opt"))]
macro_rules! perf_assert {
( $cond: expr ) => {
if !$cond {
unsafe { std::hint::unreachable_unchecked() }
}
};
}
So this is controlled by a feature unsafe_opt ( disabled by default! ). I had to adjust the module header which forbids unsafe code, to allow the macro to be used:
#![cfg_attr(
any(debug_assertions, not(feature = "unsafe_opt")),
forbid(unsafe_code)
)] // see util::perf_assert! macro
Then I use the macro as follows in my Heap indexing code to "suppress" index checking:
perf_assert!(x < self.0.len());
&self.0[x]
( Full code here: heap.rs - source )
Finally I made a test with timing ( included in module above ) that shows about a 20% performance gain for heap operations, which actually surprised me a little as I didn't think it would make that much difference. Of course in a real system the time spent doing heap operations may well be negligible, that is harder to say. But at least I could measure something! My test output:
C:\Users\ano31\Rust\RustDB>benchheap
C:\Users\ano31\Rust\RustDB>cargo test heap --release -- --nocapture
Finished release [optimized] target(s) in 0.13s
Running unittests src\lib.rs (target\release\deps\rustdb-79526361b2f7e23f.exe)
running 2 tests
test heap::test ... ok
heap test average time=591 sorted results=[577, 578, 583, 584, 585, 591, 599, 603, 604, 608]
test heap::test2 ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 9 filtered out; finished in 0.07s
C:\Users\ano31\Rust\RustDB>cargo test heap --release --features unsafe_opt -- --nocapture
Finished release [optimized] target(s) in 0.05s
Running unittests src\lib.rs (target\release\deps\rustdb-98231b58c6b06f4c.exe)
running 2 tests
test heap::test ... ok
heap test average time=510 sorted results=[480, 484, 504, 507, 517, 519, 522, 523, 524, 525]
test heap::test2 ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 9 filtered out; finished in 0.06s
C:\Users\ano31\Rust\RustDB>