我将对具有10 ^ 6 +个元素的多个向量进行逐元素乘法。在性能分析中,这被标记为我的代码中最慢的部分之一,那么我该如何改进呢?
charvalue == 31
答案 0 :(得分:7)
在Vec
或切片上使用索引器运算符时,编译器必须检查索引是在范围内还是在范围之外。
但是,当您使用迭代器时,将省略这些边界检查,因为已经精心编写了迭代器以确保它们永远不会超出边界。此外,由于借用在Rust中是如何工作的,因此当迭代器存在于该数据结构上时,该数据结构将无法更改(通过该迭代器本身除外),因此有效范围在迭代期间是不可能的。
由于要同时迭代两个不同的数据结构,因此需要使用zip
迭代器适配器。 zip
会在一个迭代器用完后立即停止,因此验证两个向量的长度相同仍然很重要。 zip
产生一个元组的迭代器,其中每个元组在两个原始迭代器中的相同位置包含项。然后,您可以使用map
将每个元组转换为两个值的乘积。最后,您需要将map
产生的新迭代器collect
变成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()
}
注意:我已经将签名更改为采用切片,而不是对矢量的引用。有关更多信息,请参见Why is it discouraged to accept a reference to a String (&String), Vec (&Vec), or Box (&Box) as a function argument?。