将负符号添加到无符号的更快方法

Faster way of adding negative signed to unsigned

假设我有 a: usize 和一个负数 b:isize 我如何实现以下语义 - 以最快的方式将 a 减去 b 的绝对值?

我已经想到了a - (b.abs() as usize),但我想知道是否有更快的方法。也许是位操作的东西?

为什么你认为这很慢?如果将该代码放入函数中并编译,在 x86-64 linux 上,它会生成以下内容:

_ZN6simple20h0f921f89f1d823aeeaaE:
    mov rax, rsi
    neg rax
    cmovl rax, rsi
    sub rdi, rax
    mov rax, rdi
    ret

这是假设它没有被内联......我不得不工作几分钟以阻止优化器为了获得上述内容而做的事情。

这并不是说它绝对不能做得更快,但我不相信它可以做得更快 much

如果b保证为负数,那么就可以a + b.

在 Rust 中,我们必须首先将一个操作数转换为与另一个操作数相同的类型,然后我们必须使用 wrapping_add 而不是简单地使用运算符 +,因为调试会在溢出时产生恐慌(在 usize 上使用 + 时会发生溢出,因为负数在转换后会变成非常大的正数)。

fn main() {
    let a: usize = 5;
    let b: isize = -2;
    let c: usize = a.wrapping_add(b as usize);
    println!("{}", c); // prints 3
}

通过优化,wrapping_add 编译为单个 add 指令。