我如何有效地实施:
fn shorten(arg: [u8; 32]) -> [u8; 30] {
???
}
它丢弃了最后两个字节?
显然,我可以使用for循环,并在堆栈上创建一个新的较短的array.
对于编译器来说,appears有机会将[u8; 32]
留在堆栈上,并且只使用其中的[u8; 30]
.
通常我会使用切片,但在这里我需要返回一个较短的array.
我如何有效地实施:
fn shorten(arg: [u8; 32]) -> [u8; 30] {
???
}
它丢弃了最后两个字节?
显然,我可以使用for循环,并在堆栈上创建一个新的较短的array.
对于编译器来说,appears有机会将[u8; 32]
留在堆栈上,并且只使用其中的[u8; 30]
.
通常我会使用切片,但在这里我需要返回一个较短的array.
这是直截了当的答案没有多大价值的问题之一.但让我们从直截了当的答案开始:您可以将函数实现为
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
}
忽略函数调用的脚手架,这些指令都优化为四条x86指令.
movups xmm0, xmmword ptr [rsi]
movups xmm1, xmmword ptr [rsi + 14]
movups xmmword ptr [rdi + 14], xmm1
movups xmmword ptr [rdi], xmm0
(看到有重叠加载/存储的诡计了吗?聪明的.-.-)godbolt
现在,对于不直接的答案:问题是,孤立地看待fn shorten
个是没有意义的:
shorten
是它自己的函数并返回拥有的[u8; 30]
,它就必须复制,因为返回值是与参数不同的值.它不能返回指向参数的指针,因为签名promise 返回值.shorten
是短的,LLVM肯定会内联它.然后问题是,LLVM是否能计算出,无论使用shorten
的结果是什么,都会对[u8; 32]
满意.它是否能做到这一点并不能用你提供的信息来回答.最后,shorten
是四条x86指令.您是否真的处于这样一种情况:这会占用您的执行时间的很大一部分?