FP Flashcards
(3 cards)
let nums = vec![1, 2, 3];
let new_nums: Vec<i32> = nums.iter().map(|x| x * 2).collect();
println!("{:?}", new_nums); // [2, 4, 6]</i32>
这里的iter()生成的是什么?map会改变nums吗?
记住:nums.iter() 生成的是 不可变引用 (&T) 的迭代器。
map不会修改 nums,而是创建一个新列表 new_nums
let numbers = vec![1, 2, 3];
let result: Vec<i32> = numbers.iter().map(|x| x + 2).collect();
println!("{:?}", result);
那个绝对值符号是什么?</i32>
是一个闭包(closure)。在 Rust 里,.map()需要一个函数,用来对每个元素进行操作。闭包closure是 Rust 里最方便传递小型匿名函数的方式,所以map(|x| x + 2) 其实就是在传递一个闭包。
Rust 的闭包(closure)是 可以捕获外部变量 并 作为参数传递的匿名函数。
SIMD?FMA?map fusion?
单指令多数据流:
arr = [1, 2, 3, 4]
newArr = map (+1) arr – 计算可并行
示例(函数式编程 - 编译器自动并行):
因为 arr 不会被修改,编译器可以自动把 map转换成 SIMD 指令,大幅加速计算。
arr = [1, 2, 3, 4]
newArr = map (+1) arr – 计算可并行
因为 arr不会被修改,编译器可以自动把 map转换成 SIMD 指令,大幅加速计算。
—————————————
某些处理器(CPU)还能做更底层的优化!许多现代 CPU 具有 “Fused Multiply-Add(FMA)” 指令,可以在 一个指令 内执行 a * b + c
let result = a * b + c;
传统 CPU 需要执行 两个指令。
————————
let result: Vec<i32> = numbers.iter()
.map(|x| x + 2)
.map(|x| x * 2)
.map(|x| x / 3)
.collect();
没副作用的话可以把他们合并成一个:
let result: Vec<i32> = numbers.iter()
.map(|x| ((x + 2) * 2) / 3)
.collect();</i32></i32>