我有一个函数字符串,它们生成数组并将它们返回到调用堆栈中。大致的函数签名是:
fn solutions(...) -> [[u64; M]; N] { /* run iterator on lots of problem sets */ }
fn generate_solutions(...) -> impl Iterator<Item=[u64; M]> { /* call find_solution on different problem sets */ }
fn find_solution(...) -> [u64; M] { /* call validate_candidate with different candidates to find solution */ }
fn validate_candidate(...) -> Option<[u64; M]> {
let mut table = [0; M];
// do compute intensive work
if works { Some(table) } else { None }
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,Rust 实际上不会将数组复制到调用堆栈上,而是会优化副本。
但这不是我所看到的。当我切换到 时Vec
,我发现速度提高了 20 倍,唯一的变化[u64;M]
是Vec<u64>
. 所以,它完全是一遍又一遍地复制数组。
那么为什么是 array 而不是Vec
,每个人总是会问。嵌入式环境。no_std
。
如何鼓励 Rust 优化这些数组副本?
不幸的是,保证缺少副本目前是 Rust 中尚未解决的问题。要获得所需的特征,您需要显式传入应写入的存储(\xe2\x80\x9cout 参数\xe2\x80\x9d 模式):
\nfn solutions(..., out: &mut [[u64; M]; N]) {...}\nfn find_solution(..., out: &mut [u64; M]) {...}\nfn validate_candidate(table: &mut [u64; M]) -> bool { \n // write into table\n works\n}\n
Run Code Online (Sandbox Code Playgroud)\n因此,您还必须找到Iterator
for的替代方案generate_solutions
(因为 usingIterator
意味着所有结果可以同时存在而不会相互覆盖)。