x.abs() 与 Rust 中的否定 (-x) 性能,当 x 是一个已知的负数时

x.abs() vs negation (-x) performance in Rust, when x is a known negative number

考虑到 x 是一个已知的负数,在内部哪种方法更有效?结果正数被转换为无符号类型。

let x = -1;
let y = x.abs() as u32;
let z = -x as u32;

检查 playground 中的这两种情况,我们得到以下程序集:

playground::abs:
    movl    %edi, %eax
    negl    %eax
    cmovll  %edi, %eax
    retq

playground::negate:
    movl    %edi, %eax
    negl    %eax
    retq

然而,如果优化器知道 x 的值确实是负数,那么这两个版本就变得等价了。比如这两个函数在语义上都是no-ops:

pub fn extending_abs(x: u8) -> u32 {
    abs(-(x as i32))
}

pub fn extending_negate(x: u8) -> u32 {
    negate(-(x as i32))
}

他们两个的集会确实consists only of the zero-extension:

playground::extending_abs:
    movzbl  %dil, %eax
    retq

playground::extending_negate:
    movzbl  %dil, %eax
    retq