如何提高Rust中按元素乘法的性能?

时间:2019-02-09 04:38:33

标签: performance optimization rust

我将对具有10 ^ 6 +个元素的多个向量进行逐元素乘法。在性能分析中,这被标记为我的代码中最慢的部分之一,那么我该如何改进呢?

charvalue == 31

1 个答案:

答案 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?