Skip to content

Commit 35d63ba

Browse files
authored
Optimize FromIterator, retain and retain_mut (#80)
1 parent ac4c15d commit 35d63ba

File tree

3 files changed

+42
-31
lines changed

3 files changed

+42
-31
lines changed

benches/soa.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,24 @@ fn soa_big_do_work_100k(bencher: &mut Bencher) {
168168
})
169169
}
170170

171+
fn soa_big_do_work_simple_100k(bencher: &mut Bencher) {
172+
let vec = Big::soa_vec(100_000);
173+
bencher.iter(||{
174+
let mut s = 0.0;
175+
for elem in vec.iter() {
176+
s += elem.position.0 + elem.velocity.0;
177+
}
178+
s
179+
})
180+
}
181+
171182

172183
benchmark_group!(aos,
173184
aos_small_push, aos_big_push, aos_small_do_work_100k, aos_big_do_work_10k,
174185
aos_big_do_work_100k
175186
);
176187
benchmark_group!(soa,
177188
soa_small_push, soa_big_push, soa_small_do_work_100k, soa_big_do_work_10k,
178-
soa_big_do_work_100k
189+
soa_big_do_work_100k, soa_big_do_work_simple_100k,
179190
);
180191
benchmark_main!(soa, aos);

soa-derive-internal/src/iter.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,10 @@ pub fn derive(input: &Input) -> TokenStream {
235235

236236
impl std::iter::FromIterator<#name> for #vec_name {
237237
fn from_iter<T: IntoIterator<Item=#name>>(iter: T) -> Self {
238-
let mut result = #vec_name::new();
239-
for element in iter {
240-
result.push(element);
241-
}
238+
let iterator = iter.into_iter();
239+
let capacity = iterator.size_hint().1.unwrap_or(0);
240+
let mut result = #vec_name::with_capacity(capacity);
241+
iterator.for_each(|element| result.push(element));
242242
result
243243
}
244244
}

soa-derive-internal/src/vec.rs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ pub fn derive(input: &Input) -> TokenStream {
196196
/// ::insert()`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.insert).
197197
#[allow(clippy::forget_non_drop)]
198198
pub fn insert(&mut self, index: usize, element: #name) {
199-
if index > self.len() {
199+
if index >= self.len() {
200200
panic!("index out of bounds: the len is {} but the index is {}", self.len(), index);
201201
}
202202

@@ -213,7 +213,7 @@ pub fn derive(input: &Input) -> TokenStream {
213213
/// Similar to [`std::mem::replace()`](https://doc.rust-lang.org/std/mem/fn.replace.html).
214214
#[allow(clippy::forget_non_drop)]
215215
pub fn replace(&mut self, index: usize, element: #name) -> #name {
216-
if index > self.len() {
216+
if index >= self.len() {
217217
panic!("index out of bounds: the len is {} but the index is {}", self.len(), index);
218218
}
219219

@@ -317,43 +317,43 @@ pub fn derive(input: &Input) -> TokenStream {
317317
#[doc = #vec_name_str]
318318
/// ::retain()`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain).
319319
pub fn retain<F>(&mut self, mut f: F) where F: FnMut(#ref_name) -> bool {
320-
let len = self.len();
321-
let mut del = 0;
322-
323-
{
324-
let mut slice = self.as_mut_slice();
325-
for i in 0..len {
326-
if !f(slice.get(i).unwrap()) {
327-
del += 1;
328-
} else if del > 0 {
329-
slice.swap(i - del, i);
320+
let mut slice = self.as_mut_slice();
321+
let len = slice.len();
322+
let mut write_idx = 0;
323+
324+
for read_idx in 0..len {
325+
if f(slice.get(read_idx).unwrap()) {
326+
if write_idx != read_idx {
327+
slice.swap(write_idx, read_idx);
330328
}
329+
write_idx += 1;
331330
}
332331
}
333-
if del > 0 {
334-
self.truncate(len - del);
332+
333+
if write_idx < len {
334+
self.truncate(write_idx);
335335
}
336336
}
337337

338338
/// Similar to [`
339339
#[doc = #vec_name_str]
340340
/// ::retain_mut()`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain_mut).
341341
pub fn retain_mut<F>(&mut self, mut f: F) where F: FnMut(#ref_mut_name) -> bool {
342-
let len = self.len();
343-
let mut del = 0;
344-
345-
{
346-
let mut slice = self.as_mut_slice();
347-
for i in 0..len {
348-
if !f(slice.get_mut(i).unwrap()) {
349-
del += 1;
350-
} else if del > 0 {
351-
slice.swap(i - del, i);
342+
let mut slice = self.as_mut_slice();
343+
let len = slice.len();
344+
let mut write_idx = 0;
345+
346+
for read_idx in 0..len {
347+
if f(slice.get_mut(read_idx).unwrap()) {
348+
if write_idx != read_idx {
349+
slice.swap(write_idx, read_idx);
352350
}
351+
write_idx += 1;
353352
}
354353
}
355-
if del > 0 {
356-
self.truncate(len - del);
354+
355+
if write_idx < len {
356+
self.truncate(write_idx);
357357
}
358358
}
359359

0 commit comments

Comments
 (0)