performance - 如何根据条件重复向量中的某些元素?

标签 performance vector rust mutability

我在 kata 期间遇到了这个问题.我更具可读性的实现如下:

use std::vec::Vec;

fn repeat_even(v: Vec<i32>) -> Vec<i32> {
    v.into_iter().flat_map(|x| match x % 2 { 0 => vec![x, x], _ => vec![x] }).collect()
}

fn main() {
    let v = vec![1, 2, 3, 4, 6];
    assert_eq!(repeat_even(v), vec![1, 2, 2, 3, 4, 4, 6, 6]);
}

我有两个问题:

  • 是否有必要再创建一个Vec?是否可以使用相同的 Vec,即在迭代时修改它?

  • 我认为我的解决方案效率低下:我分配了很多向量,但我无法保证这会得到优化。是否有更好的解决方案:可读且分配更少?

最佳答案

您可以在同一个向量中执行此操作,但每次遇到偶数时都需要移动向量的其余部分(在翻倍的数字之后),这是低效的。最好使用一个新的向量和一个简单的循环来完成:

fn main() {
    let v = vec![1, 2, 3, 4, 6];

    let mut v2 = Vec::with_capacity(v.len() + v.iter().filter(|&n| n % 2 == 0).count());

    for n in v {
        v2.push(n);
        if n % 2 == 0 { v2.push(n) }
    }

    assert_eq!(v2, vec![1, 2, 2, 3, 4, 4, 6, 6]);
}

此解决方案仅分配一次内存,其中包含容纳所有数字(包括双倍偶数)所需的确切空间。

关于performance - 如何根据条件重复向量中的某些元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44082810/

相关文章:

向量作为 Julia 中的指数

performance - 通过数组操作高效搜索包含子排列的排列?

c++ - 避免 RAII 计时器对象中的虚假构造和破坏

java - 在长时间运行的线程完成之前显示 Android 布局?

performance - 并行文件下载

c++ - 以相反的顺序将一个 vector 复制到另一个 vector

C++ 将 vector<string> 的排序内容写入文件

rust - SDL2如何安装和使用 "gfx"功能

multithreading - 如何将对堆栈变量的引用传递给线程?

rust - 有没有更惯用的方法来使用生命周期中的 `io::Read` 等特征?