Skip to content

Commit a461776

Browse files
committed
auto merge of #8225 : huonw/rust/vec-iter, r=graydon
Closes #8212. Before: ```llvm %sum.028 = phi i64 [ %23, %match_else ], [ 0, %"normal return" ] %.sroa.0.027 = phi i64* [ %21, %match_else ], [ %12, %"normal return" ] %19 = ptrtoint i64* %.sroa.0.027 to i64 %20 = add i64 %19, 8 %21 = inttoptr i64 %20 to i64* %22 = load i64* %.sroa.0.027, align 8 %23 = add i64 %22, %sum.028 %24 = inttoptr i64 %20 to %"enum.std::libc::types::common::c95::c_void[#1]"* %25 = icmp eq %"enum.std::libc::types::common::c95::c_void[#1]"* %24, %16 %26 = icmp eq i64 %20, 0 %or.cond = or i1 %25, %26 ``` ``` test vec::bench::iterator ... bench: 87 ns/iter (+/- 7) test vec::bench::mut_iterator ... bench: 87 ns/iter (+/- 10) ``` After: ```llvm %sum.028 = phi i64 [ %21, %match_else ], [ 0, %"normal return" ] %.sroa.0.027 = phi i64* [ %19, %match_else ], [ %12, %"normal return" ] %19 = getelementptr i64* %.sroa.0.027, i64 1 %20 = load i64* %.sroa.0.027, align 8 %21 = add i64 %20, %sum.028 %22 = bitcast i64* %19 to %"enum.std::libc::types::common::c95::c_void[#1]"* %23 = icmp eq %"enum.std::libc::types::common::c95::c_void[#1]"* %22, %16 %24 = icmp eq i64* %19, null %or.cond = or i1 %23, %24 ``` ``` test vec::bench::iterator ... bench: 79 ns/iter (+/- 8) test vec::bench::mut_iterator ... bench: 78 ns/iter (+/- 2) ``` (NB. I'm not 100% sure the benchmarks were set-up correctly, so take them with a grain of salt.)
2 parents f1c1f92 + 29000c0 commit a461776

File tree

1 file changed

+51
-8
lines changed

1 file changed

+51
-8
lines changed

src/libstd/vec.rs

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,11 +2141,15 @@ macro_rules! iterator {
21412141
None
21422142
} else {
21432143
let old = self.ptr;
2144-
// purposefully don't use 'ptr.offset' because for
2145-
// vectors with 0-size elements this would return the
2146-
// same pointer.
2147-
self.ptr = cast::transmute(self.ptr as uint +
2148-
sys::nonzero_size_of::<T>());
2144+
self.ptr = if sys::size_of::<T>() == 0 {
2145+
// purposefully don't use 'ptr.offset' because for
2146+
// vectors with 0-size elements this would return the
2147+
// same pointer.
2148+
cast::transmute(self.ptr as uint + 1)
2149+
} else {
2150+
self.ptr.offset(1)
2151+
};
2152+
21492153
Some(cast::transmute(old))
21502154
}
21512155
}
@@ -2171,9 +2175,12 @@ macro_rules! double_ended_iterator {
21712175
if self.end == self.ptr {
21722176
None
21732177
} else {
2174-
// See above for why 'ptr.offset' isn't used
2175-
self.end = cast::transmute(self.end as uint -
2176-
sys::nonzero_size_of::<T>());
2178+
self.end = if sys::size_of::<T>() == 0 {
2179+
// See above for why 'ptr.offset' isn't used
2180+
cast::transmute(self.end as uint - 1)
2181+
} else {
2182+
self.ptr.offset(-1)
2183+
};
21772184
Some(cast::transmute(self.end))
21782185
}
21792186
}
@@ -3566,3 +3573,39 @@ mod tests {
35663573
assert!(cnt == 3);
35673574
}
35683575
}
3576+
3577+
#[cfg(test)]
3578+
mod bench {
3579+
use extra::test::BenchHarness;
3580+
use vec;
3581+
use option::*;
3582+
3583+
#[bench]
3584+
fn iterator(bh: &mut BenchHarness) {
3585+
// peculiar numbers to stop LLVM from optimising the summation
3586+
// out.
3587+
let v = vec::from_fn(100, |i| i ^ (i << 1) ^ (i >> 1));
3588+
3589+
do bh.iter {
3590+
let mut sum = 0;
3591+
foreach x in v.iter() {
3592+
sum += *x;
3593+
}
3594+
// sum == 11806, to stop dead code elimination.
3595+
if sum == 0 {fail!()}
3596+
}
3597+
}
3598+
3599+
#[bench]
3600+
fn mut_iterator(bh: &mut BenchHarness) {
3601+
let mut v = vec::from_elem(100, 0);
3602+
3603+
do bh.iter {
3604+
let mut i = 0;
3605+
foreach x in v.mut_iter() {
3606+
*x = i;
3607+
i += 1;
3608+
}
3609+
}
3610+
}
3611+
}

0 commit comments

Comments
 (0)