Home > OS >  Swapping vectors [closed]
Swapping vectors [closed]

Time:09-22

I need to assign the values of one vector to another, like:

let mut vec_a: Vec<f64> = vec![0.1; 100];
let mut vec_b: Vec<f64> = vec![0.1; 100];

// Do something with vec_a. Real vectors are ~1e6 long    
unsafe {
    vec_b = Vec::from_raw_parts(&vec_a, vec_a.len(), vec_a.len());
}

I'm looking for help to answer these questions:

Is there a more efficient and safer way of doing this?

Why it has to be under unsafe code if everything is being handled by the same application/code?

If it is the correct way, will it have a difference if instead of Vec::from_raw_parts use std::slice::from_raw_parts?

The reason behind this need is to avoid copying the data. This may happen with a high frequency and every time, one vector will be the storage to keep track of a best solution (let's say vec_a), the other one will be exploring other solutions. When a better solution is found, the only thing that needs to be changed is the pointer to the vector, now vec_a stores the best solution that was found in vec_b and vec_b can keep exploring different solutions.

CodePudding user response:

The naive answer is fairly performant. A simple assignment (best_solution = solution) doesn't do a deep copy of the elements, it only transfers ownership and destroys the source.

let mut best_solution = vec![0.1; 100];
loop {
    let solution = generate_solution();
    if solution > best_solution {
        best_solution = solution;
    }
}

One thing you can do to make it more performant is to reduce allocations by using a persistent vec as scratch space (you may be getting at this in the code in your post). In that case you would use std::mem::swap to avoid destroying the scratch vec.

let mut best_solution = vec![0.1; 100];
let mut scratch_solution = vec![0.1; 100];
loop {
    generate_solution(&mut scratch_solution);
    if scratch_solution > best_solution {
        std::mem::swap(&mut best_solution, &mut scratch_solution);
    }
}

CodePudding user response:

You should use just swap and moves for this. Check this test that shows that swapping vectors only change pointers:

fn main() {
    let mut v1 = vec![0; 100];
    let mut v2 = vec![0; 100];
    let old_ptr1 = v1.as_ptr();
    let old_ptr2 = v2.as_ptr();
    std::mem::swap(&mut v1, &mut v2);
    assert_eq!(old_ptr1, v2.as_ptr());
    assert_eq!(old_ptr2, v1.as_ptr());
}

CodePudding user response:

Hard to tell your intentions, but if you want to move all the values of source vector into a destination vector without loosing content of destination, then you can swap vectors contents without copying data. E.g.

fn main() {
    let mut vec_a: Vec<f64> = vec![0.1; 100];
    let mut vec_b: Vec<f64> = vec![0.2; 100];
    println!("{}", vec_a[0]); // 0.1
    println!("{}", vec_b[0]); // 0.2
    
    let (mut vec_a, mut vec_b) = (vec_b, vec_a);
    println!("{}", vec_a[0]); // 0.2
    println!("{}", vec_b[0]); // 0.1
}
  • Related