Skip to content

Commit 86415f7

Browse files
committed
Use counted loop in unordered_foreach_mut
This improves the generated code for the inner loop we use for .assign_scalar() and other array operations with a single scalar. The old code would generate something that looked like it assumed the element being written to and the iterator's pointer could alias another. This new version is unrolled and vectorized to a larger degree, but it does still not produce memset for some inputs like rust could do in january 2016. name before ns/iter after ns/iter diff ns/iter diff % assign_scalar_2d_corder 1,631 868 -763 -46.78% assign_scalar_2d_cutout 1,704 1,332 -372 -21.83% assign_scalar_2d_forder 1,628 869 -759 -46.62% assign_zero_2d_corder 1,602 855 -747 -46.63% assign_zero_2d_cutout 1,703 1,335 -368 -21.61% assign_zero_2d_forder 1,618 858 -760 -46.97% before: Using the slice iterator after: using indexed loop.
1 parent 350a92e commit 86415f7

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

src/impl_methods.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1041,8 +1041,9 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
10411041
where F: FnMut(B, &'a A) -> B, A: 'a
10421042
{
10431043
if let Some(slc) = self.as_slice() {
1044-
for elt in slc {
1045-
init = f(init, elt);
1044+
// FIXME: Use for loop when slice iterator is perf is restored
1045+
for i in 0..slc.len() {
1046+
init = f(init, &slc[i]);
10461047
}
10471048
return init;
10481049
}

src/lib.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -510,12 +510,20 @@ impl<A, S, D> ArrayBase<S, D>
510510
F: FnMut(&mut A)
511511
{
512512
if let Some(slc) = self.as_slice_memory_order_mut() {
513-
for elt in slc {
514-
f(elt);
513+
// FIXME: Use for loop when slice iterator is perf is restored
514+
for i in 0..slc.len() {
515+
f(&mut slc[i]);
515516
}
516517
return;
517518
}
518-
for row in self.inner_iter_mut() {
519+
for mut row in self.inner_iter_mut() {
520+
if let Some(slc) = row.as_slice_mut() {
521+
// FIXME: Use for loop when slice iterator is perf is restored
522+
for i in 0..slc.len() {
523+
f(&mut slc[i]);
524+
}
525+
continue;
526+
}
519527
for elt in row {
520528
f(elt);
521529
}

0 commit comments

Comments
 (0)