当 x 是已知负数时,Rust 中的 x.abs() 与求反 (-x) 性能比较

rea*_*dul 0 negative-number rust

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

let x = -1;
let y = x.abs() as u32;
let z = -x as u32;
Run Code Online (Sandbox Code Playgroud)

Cer*_*rus 5

在操场上检查这两个案例,我们得到以下程序集:

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

playground::negate:
    movl    %edi, %eax
    negl    %eax
    retq
Run Code Online (Sandbox Code Playgroud)

但是,如果优化器知道 的值x确实为负,则这两个版本变得等效。例如,这两个函数在语义上都是空操作:

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

pub fn extending_negate(x: u8) -> u32 {
    negate(-(x as i32))
}
Run Code Online (Sandbox Code Playgroud)

它们的汇编确实只包含零扩展

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

playground::extending_negate:
    movzbl  %dil, %eax
    retq
Run Code Online (Sandbox Code Playgroud)