我有一些代码,我经常在模式下使用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);
}

最佳答案

两种方法的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

关于performance - 模式下的unwrap()是否已优化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44177206/

10-09 00:29