如何缩短 Rust 中的数组

fad*_*bee 2 arrays rust

我怎样才能有效地实施:

fn shorten(arg: [u8; 32]) -> [u8; 30] {
    ???
}
Run Code Online (Sandbox Code Playgroud)

它会丢弃最后两个字节吗?

显然我可以使用 for 循环,并在堆栈上创建一个新的较短数组。

编译器似乎有机会离开堆栈[u8; 32]仅使用它[u8; 30]的。

通常我会使用切片,但这里我需要返回一个较短的数组。

Cae*_*sar 7

这是直接回答并没有多大价值的问题之一。但让我们从直接的答案开始:您可以将函数实现为

fn shorten(arg: [u8; 32]) -> [u8; 30] {
    std::array::from_fn(|i| arg[i])
}
// or
fn shorten(arg: [u8; 32]) -> [u8; 30] {
    arg[..30].try_into().unwrap()
}
// or
fn shorten(arg: [u8; 32]) -> [u8; 30] {
    let mut ret = [0; 30];
    ret.copy_from_slice(&arg[..30]);
    ret
}
// or
fn shorten(arg: [u8; 32]) -> [u8; 30] {
    let mut ret = [0; 30];
    for i in 0..30 {
        ret[i] = arg[i];
    }
    ret
}
Run Code Online (Sandbox Code Playgroud)

忽略函数调用的脚手架,这些都优化至四个 x86 指令。

movups  xmm0, xmmword ptr [rsi]
movups  xmm1, xmmword ptr [rsi + 14]
movups  xmmword ptr [rdi + 14], xmm1
movups  xmmword ptr [rdi], xmm0
Run Code Online (Sandbox Code Playgroud)

(看到那里的诡计,重叠加载/存储?聪明。-.-

现在,对于答案的非直接部分:问题是孤立地看待是没有意义的fn shorten

  • 只要shorten是它自己的函数并返回一个owned [u8; 30],它就必须复制一份,因为返回值是与参数不同的值。它不能返回指向参数的指针,因为签名承诺它返回一个值。
  • shorten很短,LLVM 肯定会内联它。然后的问题是 LLVM 是否可以弄清楚,无论使用 的结果,shorten也会对[u8; 32]. 它是否可以做到这一点与您提供的信息无关。

最后shorten是四个 x86 指令。您是否真的处于这样的状态:这占用了您执行时间的很大一部分?