mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-12 23:50:20 +03:00
Fix over-allocation in List::from_iter
This commit is contained in:
parent
ba7b98bdaa
commit
b14d9b5244
@ -549,7 +549,7 @@ impl<T: Clone> FromIterator<T> for RocList<T> {
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
let mut iter = into.into_iter();
|
||||
let iter = into.into_iter();
|
||||
|
||||
if std::mem::size_of::<T>() == 0 {
|
||||
let count = iter.count();
|
||||
@ -566,25 +566,23 @@ impl<T: Clone> FromIterator<T> for RocList<T> {
|
||||
Self::with_capacity(init_capacity)
|
||||
};
|
||||
|
||||
loop {
|
||||
let start = list.length;
|
||||
let elements = list.elements.unwrap().as_ptr();
|
||||
for i in start..list.capacity {
|
||||
if let Some(new_elem) = iter.next() {
|
||||
unsafe {
|
||||
elements
|
||||
.add(i)
|
||||
.write(ptr::read(&ManuallyDrop::new(new_elem)));
|
||||
}
|
||||
list.length += 1;
|
||||
} else {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
let mut elements = list.elements.unwrap().as_ptr();
|
||||
for new_elem in iter {
|
||||
// If the size_hint didn't give us a max, we may need to grow. 1.5x seems to be good, based on:
|
||||
// https://archive.ph/Z2R8w and https://github.com/facebook/folly/blob/1f2706/folly/docs/FBVector.md
|
||||
list.reserve(list.capacity / 2);
|
||||
if list.length == list.capacity {
|
||||
list.reserve(list.capacity / 2);
|
||||
elements = list.elements.unwrap().as_ptr();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
elements
|
||||
.add(list.length)
|
||||
.write(ptr::read(&ManuallyDrop::new(new_elem)));
|
||||
}
|
||||
list.length += 1;
|
||||
}
|
||||
|
||||
list
|
||||
}
|
||||
}
|
||||
|
@ -162,6 +162,7 @@ mod test_roc_std {
|
||||
let from_slice = RocList::from_slice(&elems);
|
||||
let from_iter = RocList::from_iter(elems);
|
||||
assert_eq!(from_iter, from_slice);
|
||||
assert_eq!(from_iter.capacity(), from_slice.capacity());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user