unwrap()是否在优化的模式下?

时间:2017-05-25 09:39:42

标签: performance rust pattern-matching

我有一些代码,我常常在模式下使用unwrap(),我可以肯定它不会恐慌。其中一些部分属于性能关键功能,所以我想知道是否最好摆脱这些unwrap()以支持未经检查的适用函数变体。但是,我没有看到#[bench]测试的任何差异,两个变体的ASM看起来与我非常相似(虽然我不是专家)。

Rust似乎能够优化这些案例;我是对的还是我应该使用未经检查的函数而不是unwrap()

MCVE:

use self::Foo::*;
use self::Error::*;

#[derive(Debug)]
enum Foo {
    Bar(Box<Foo>),
    Baz
}

#[derive(Debug)]
enum Error {
    NotBar
}

impl Foo {
    fn bar_mut_ref(&mut self) -> Result<&mut Foo, Error> {
        match *self {
            Bar(ref mut foo) => Ok(foo),
            _ => Err(NotBar)
        }
    }

    fn bar_mut_ref_unchecked(&mut self) -> &mut Foo {
        match *self {
            Bar(ref mut foo) => foo,
            _ => panic!("bar_mut_ref_unchecked() called on a non-Bar!")
        }
    }

    fn bazify(&mut self) {
        match *self {
            Bar(_) => { *self = Baz },
            _ => ()
        }
    }
}

fn do_stuff_with_foo(foo: &mut Foo) {
    match *foo {
        Bar(_) => {
            foo.bar_mut_ref().unwrap().bazify(); // is _unchecked() better here?
            // underscore was used because foo is assigned to a new value here
        },
        _ => {}
    }
}

fn main() {
    let mut foo = Bar(Box::new(Bar(Box::new(Baz))));
    do_stuff_with_foo(&mut foo);
    println!("{:?}", foo);
}

1 个答案:

答案 0 :(得分:1)

这两种方法中的A more direct comparison产生相同的ASM,因此至少对于这个简单的例子,答案似乎是:是的,这样的情况可以被优化掉。

example::do_stuff_with_foo:
        push    rbp
        mov     rbp, rsp
        push    rbx
        push    rax
        mov     rbx, qword ptr [rdi]
        test    rbx, rbx
        je      .LBB1_3
        cmp     qword ptr [rbx], 0
        je      .LBB1_3
        mov     rdi, rbx
        call    core::ptr::drop_in_place
        mov     qword ptr [rbx], 0
.LBB1_3:
        add     rsp, 8
        pop     rbx
        pop     rbp
        ret