[Solved] How to fill a Vec with a value


#1

What is the best way to assign a value to the all elements in a Vec.
Assigning new vec like v = vec![2.0; 20] is simple but it seems to consume new heap memory, so I did it by save the original length, then clear, then resize like code below. But is there any other better option?

fn main() {
    let mut v = vec![0.0; 20];
    println!("{:?}", v);
    println!("{}", v.capacity());
    let n = v.len();
    v.clear();
    println!("{:?}", v);
    println!("{}", v.capacity());
    v.resize(n, 2.0);
    println!("{:?}", v);
    println!("{}", v.capacity());
}

#2

If you want a new Vec of length n where it’s pre-filled with a particular number then the best way is probably to use vec![2.0; 20]. A Vec is backed by an array allocated on the heap, so no matter what if you are using Vec it’s going to require consuming some heap memory.

Otherwise if you’re just trying to reuse an old Vecthen clearing it and resizing seems to be about the best way. You need that clear step because for a Vec holding non-trivial data (i.e. something which isn’t Copy), you need to make sure to call the destructor for each element before you can reuse the slot it’s in.

Otherwise if it’s just a Vec of floats and you don’t care about destructors, by far the fastest (notice I say “fastest”, not “best”) method would be to use something like libc::memset.

extern crate libc;
use std::mem;

fn main() {
    let mut buffer: Vec<u32> = vec![42; 20];
    println!("{:?}", buffer);

    // overwrite the buffer with all zeros
    unsafe {
        libc::memset(
            buffer.as_mut_ptr() as _,
            0,
            buffer.len() * mem::size_of::<u32>(),
        );
    }
    println!("{:?}", buffer);
}

#3

See also


for the unfortunate lack of the obvious fill helper that you are probably looking for.

In the meantime, for a solution that iterates only once if your values have destructors, there’s:

v.iter_mut().map(|x| *x = value).count();

#4

Also keep in mind that when compiling in debug mode (by default), things aren’t optimized. If you want to measure memory consumption correctly always compile in release mode.