考虑以下代码:
enum MyError {
    BadError, NotSoBad,
}
#[inline(never)]
fn do_stuff1<T>(m: Result<T, MyError>) -> bool {
    m.is_err()
}
#[inline(never)]
fn do_stuff2<T>(m: Result<T, MyError>) -> bool {
    if let Err(MyError::BadError) = m {
        true
    } else {
        false
    }
}
生成的程序集(请参见操场):
playground::do_stuff1:
    cmpb    $1, %dil
    sete    %al
    retq
playground::do_stuff2:
    testb   %dil, %dil
    setne   %cl
    testb   %sil, %sil
    sete    %al
    andb    %cl, %al
    retq
测试result.is_err()仅产生一个字节的比较结果,这似乎是合理的,但针对特定错误的模式匹配会产生更多指令。
这是因为错误类型实际上被编码为与错误标志分开的字节。A Result<u64, MyError>的布局如下:
enum MyError {
    BadError, NotSoBad,
}
#[inline(never)]
fn do_stuff1<T>(m: Result<T, MyError>) -> bool {
    m.is_err()
}
#[inline(never)]
fn do_stuff2<T>(m: Result<T, MyError>) -> bool {
    if let Err(MyError::BadError) = m {
        true
    } else {
        false
    }
}
我的期望是,将使用单个字节对存在错误的事实和错误的变体进行编码,这将简化组装。
是否存在无法进行此优化的原因,或者是否存在一些折衷方案,使其不受欢迎?
| 归档时间: | 
 | 
| 查看次数: | 92 次 | 
| 最近记录: |