ryn*_*n1x 6 optimization performance rust
我将使用10 ^ 6 +元素对多个向量进行元素乘法.这在标题中被标记为我的代码中最慢的部分之一,所以我该如何改进它?
/// element-wise multiplication for vecs
pub fn vec_mul<T>(v1: &Vec<T>, v2: &Vec<T>) -> Vec<T>
where
T: std::ops::Mul<Output = T> + Copy,
{
if v1.len() != v2.len() {
panic!("Cannot multiply vectors of different lengths!")
}
let mut out: Vec<T> = Vec::with_capacity(v1.len());
for i in 0..(v1.len()) {
out.push(v1[i] * v2[i]);
}
out
}
Run Code Online (Sandbox Code Playgroud)
在一个Vec或一个切片上使用索引器运算符时,编译器必须检查索引是在边界内还是在边界内.
但是,当您使用迭代器时,这些边界检查将被省略,因为迭代器已经过仔细编写以确保它们永远不会读出边界.此外,由于借用如何在Rust中工作,当迭代器存在于该数据结构上时(通过迭代器本身除外),数据结构不能被变异,因此在迭代期间有效边界不可能发生变化.
由于您同时迭代两个不同的数据结构,因此您将需要使用zip迭代器适配器.zip一个迭代器耗尽就停止,因此仍然需要验证两个向量是否具有相同的长度.zip生成元组的迭代器,其中每个元组包含两个原始迭代器中相同位置的项.然后,您可以使用map将每个元组转换为两个值的乘积.最后,你会希望collect通过所产生的新的迭代map成Vec,然后可以从你的函数返回.collect使用size_hint预分配存储器用于使用矢量Vec::with_capacity.
/// element-wise multiplication for vecs
pub fn vec_mul<T>(v1: &[T], v2: &[T]) -> Vec<T>
where
T: std::ops::Mul<Output = T> + Copy,
{
if v1.len() != v2.len() {
panic!("Cannot multiply vectors of different lengths!")
}
v1.iter().zip(v2).map(|(&i1, &i2)| i1 * i2).collect()
}
Run Code Online (Sandbox Code Playgroud)
注意:我已经更改了签名以获取切片而不是对向量的引用.请参阅为什么不鼓励接受对String(&String),Vec(&Vec)或Box(&Box)的引用作为函数参数?欲获得更多信息.
| 归档时间: |
|
| 查看次数: |
168 次 |
| 最近记录: |