储存C++;向量中的函数? 这是我试图实现的C++等价: std::vector funcs; 函数emplace_back([](int n)->int{return n+1;}); int result=funcs[0](33);
如何用Rust编写上面的代码?如果您不打算将函数移动到任何特定位置,您可以让类型推断在代码块内为您完成工作,并严格定义闭包,就像它是一个普通变量一样(实际上,它是-它实现储存C++;向量中的函数? 这是我试图实现的C++等价: std::vector funcs; 函数emplace_back([](int n)->int{return n+1;}); int result=funcs[0](33);,vector,lambda,rust,closures,Vector,Lambda,Rust,Closures,如何用Rust编写上面的代码?如果您不打算将函数移动到任何特定位置,您可以让类型推断在代码块内为您完成工作,并严格定义闭包,就像它是一个普通变量一样(实际上,它是-它实现Fn或FnMut): 如果要将此lambda移出堆栈,则需要将其装箱: let my_lambda: Box<dyn Fn(u32) -> u32> = Box::new(|n| n + 1); println!("{}", my_lambda(33)); 如果它们有完全不同的签名,您将需要编写自己的结构来
Fn
或FnMut
):
如果要将此lambda移出堆栈,则需要将其装箱:
let my_lambda: Box<dyn Fn(u32) -> u32> = Box::new(|n| n + 1);
println!("{}", my_lambda(33));
如果它们有完全不同的签名,您将需要编写自己的结构来包含它们,并通过签名将它们存储起来,这不是一项简单的任务
基准案例:
- C++:
#包括 #包括 #包括 int main(int argc,字符**argv){ std::向量函数; 对于(int i=0;i<10000000;i++){ 函数push_back([&](int n){return n+1;}); int result=funcs[i](33); } }
- 锈蚀:
fn main() { let mut lambdas:Vec<Box<Fn(u32) -> u32>> = vec![]; for i in 0..10000000 { lambdas.push(Box::new(|i| i+1)); lambdas[i](3); } }
- 最大堆大小:
-------------------------------------------------------------------------------- n次(i)总计(B)有用堆(B)额外堆(B)堆栈(B) -------------------------------------------------------------------------------- 46 210,486,321 268,440,920 268,436,765 4,155 0 47 210,486,371 268,440,976 268,436,805 4,171 0 48 210,486,496 268,441,064 268,436,885 4,179 0
- C++
wrappers是堆分配的。它包含的原始lambda本身是堆栈分配的,这种行为与Rust一致std::function
- Rust更擅长内存优化,消耗了C堆大小的三分之一++
- 生锈的速度也比未加工时间快
Vec
本身在堆栈上;其指向内容的内部指针位于堆上;lambda本身也在堆上(毕竟它们是Vec
的元素)。是的,我理解这一点。我的意思是C++版本似乎更有效,因为它只做1个分配:向量内容。Rust版本实际上分配了指针向量,然后再次分配堆中的每个lambda,将指针存储在向量中。我就是这么看的。我很确定你对std::function
存储在堆栈上的看法是错误的。除了小对象优化,它们也在堆上。也就是说,损坏函数并不是衡量性能的好方法,因为在Cube和Crand两个引擎下面都有两个优化层。“但是你需要把它们装箱”——这一般不是真的。如果闭包没有捕获任何局部变量,可以将它们强制为函数指针,您可以将它们直接存储在向量中:let v:Vec i32>=Vec![n | n+1,| n | n-1]代码>。
let my_vector: Vec<Box<dyn Fn(u16) -> u16>> = vec![
Box::new(|i| i + 1),
Box::new(|i| i - 1),
];
println!("{}", my_vector[0](33))
fn main() {
let mut lambdas:Vec<Box<Fn(u32) -> u32>> = vec![];
for i in 0..10000000 {
lambdas.push(Box::new(|i| i+1));
lambdas[i](3);
}
}