arrayvec
                                
                                
                                
                                    arrayvec copied to clipboard
                            
                            
                            
                        Missing ArrayVec::resize
I'm missing the resize functionality (similar to the std::vec::Vec::resize):
fn resize(&mut self, new_len: usize, value: T)
I have to fill some items in a random order, so first the array have to be resized with some default values before indexing can start. I could use plain arrays, but I'd like to use ArrayVec for it's "virtual dynamic" size.
Is there a function for this I've missed?
Edit: This is my workaround:
(0..count).for_each(|_| self.attributes.push(Attribute::new()));
Using extend or FromIterator would be idiomatic here too, so think the existing functionality is already quite good for the use case
@bluss I tried using extend for this, but the code is not ergonomic either:
arrv.extend([0u8; 100].iter().map(|&x| x));
Also it might be a slow operation inserting bytes one by one instead of memset.
Nothing blocks adding resize to arrayvec. Extend and FromIterator are the answer to the question of missed methods, though.
Fwiw, this benchmark shows that the extend loop is pretty good but it's running into that "SetLenOnDrop problem", where the alias analysis is not good enough. It's not managing to merge the adjacent byte writes into bigger writes, because it's also writing to the array length field in the same loop.
Benchmark used:
extern crate arrayvec;
#[macro_use] extern crate bencher;
use arrayvec::ArrayVec;
use bencher::Bencher;
fn extend(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 1 << 16]>::new();
    let cap = v.capacity();
    b.iter(|| {
        v.clear();
        v.extend((0..cap).map(|_| 1));
        v[0]
    });
    b.bytes = v.capacity() as u64;
}
benchmark_group!(benches, extend);
benchmark_main!(benches);
Which means that it's the kind of sad mutable no alias issue?
Inner loop is this:
       │ 60:   mov    BYTE PTR [rsp+rbx*1+0x10021],0x1
 17,16 │       lea    edx,[rbx+0x10001]              
       │       mov    DWORD PTR [rsp+0x10024],edx   
       │       mov    BYTE PTR [rsp+rbx*1+0x10022],0x1
 15,09 │       lea    edx,[rbx+0x10002]              
       │       mov    DWORD PTR [rsp+0x10024],edx   
 11,32 │       mov    BYTE PTR [rsp+rbx*1+0x10023],0x1
 16,62 │       lea    edx,[rbx+0x10003]              
       │       mov    DWORD PTR [rsp+0x10024],edx   
  7,37 │       mov    BYTE PTR [rsp+rbx*1+0x10024],0x1
 13,84 │       lea    edx,[rbx+0x10004]              
       │       mov    DWORD PTR [rsp+0x10024],edx   
 18,60 │       add    rbx,0x4                      
       │     ↑ jne    60                          
                                    
                                    
                                    
                                
Sorry for off-topic, but there is also one other method I miss, extend_from_slice. I know that there is a write method that does exactly that, but it's not available on no_std targets, so I had to copy-paste it in my codebase.
Fwiw, -Zmutable-noalias does not help with that problem. Will post a PR to improve .extend()
@pftbest Is it the interface of the method or the performance? #74 shows that the performance of extend seems good enough for the use case.
@bluss, sorry I didn't test #74 yet. Yes, I was concerned about the performance because I'm working with a microcontroller target that is not very fast. I will come back when I'll have some measurements.
Is this method still desired? If not, an alternative might be spare_capacity_mut like rust-lang/rust#75017.
What is the current status?