我有一串生成数组并将它们返回到调用堆栈的函数.粗略地说,函数签名是:

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 }
 }

我的理解是,Rust实际上不会在调用堆栈中向上copy个数组,而是优化复制.

但这不是我所看到的.当我切换到Vec时,我看到速度提高了20倍,唯一的变化是[u64;M]Vec<u64>.所以,它完全是一遍又一遍地复制array.

所以为什么是数组而不是Vec,每个人都会问.嵌入式环境.no_std.

如何鼓励Rust优化这些数组副本?

推荐答案

不幸的是,缺少guaranteed份拷贝目前是铁 rust 公司尚未解决的问题.要获得您想要的特征,您需要显式地传入它应该写入的存储("out参数"模式):

fn solutions(..., out: &mut [[u64; M]; N]) {...}
fn find_solution(..., out: &mut [u64; M]) {...}
fn validate_candidate(table: &mut [u64; M]) -> bool { 
    // write into table
    works
}

因此,您还必须为generate_solutions找到Iterator的替代方案(因为使用Iterator意味着所有结果can同时存在,而不会相互覆盖).

Rust相关问答推荐

为什么幻影数据不能自动推断?

关于Rust 中回归的逻辑

两个相关特征的冲突实现错误

值为可变对象的不可变HashMap

铁 rust 中的共享对象实现特征

这是不是在不造成嵌套的情况下从枚举中取出想要的变体的惯用方法?

同时从不同线程调用DLL的不同函数会出现分段错误或产生STATUS_STACK_BUFFER_OVERRUN

在我的Cargo 中,当我在建筑物中使用时,找不到我可以在产品包中使用的 crate .r我如何解决这个问题?

如果包名称与bin名称相同,并且main.ars位于工作区的同一 crate 中,则无法添加对lib.ars的依赖

为什么Deref类特征不构成?

如何在AVX2中对齐/旋转256位向量?

习语选项<;T>;到选项<;U>;当T->;U用From定义

如何实现Deref;多次;?

如何将 struct 数组放置在另一个 struct 的末尾而不进行内存分段

在 Rust 中,为什么 10 个字符的字符串的 size_of_val() 返回 24 个字节?

使用启用优化的 alloc 会导致非法指令崩溃

如何迭代存储在 struct 中的字符串向量而不移动它们?

当在lambda中通过引用传递时,为什么会出现终身/类型不匹配错误?

以 `static` 为前缀的闭包是什么意思?我什么时候使用它?

使用 serde_json 进一步处理字段