std: add micro optimization to vec.with_c_str_unchecked

before:

test c_str::bench::bench_with_c_str_unchecked_long ... bench: 361 ns/iter (+/- 9)
test c_str::bench::bench_with_c_str_unchecked_medium ... bench: 75 ns/iter (+/- 2)
test c_str::bench::bench_with_c_str_unchecked_short ... bench: 60 ns/iter (+/- 9)

after:

test c_str::bench::bench_with_c_str_unchecked_long ... bench: 362 ns/iter (+/-
test c_str::bench::bench_with_c_str_unchecked_medium ... bench: 30 ns/iter (+/- 7)
test c_str::bench::bench_with_c_str_unchecked_short ... bench: 12 ns/iter (+/- 4)
This commit is contained in:
Erick Tryzelaar 2013-09-20 16:48:07 -07:00
parent 4868273d97
commit 2d878033fd

View File

@ -247,6 +247,11 @@ impl<'self> ToCStr for &'self str {
fn with_c_str<T>(&self, f: &fn(*libc::c_char) -> T) -> T { fn with_c_str<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
self.as_bytes().with_c_str(f) self.as_bytes().with_c_str(f)
} }
#[inline]
unsafe fn with_c_str_unchecked<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
self.as_bytes().with_c_str_unchecked(f)
}
} }
// The length of the stack allocated buffer for `vec.with_c_str()` // The length of the stack allocated buffer for `vec.with_c_str()`
@ -297,6 +302,23 @@ impl<'self> ToCStr for &'self [u8] {
self.to_c_str().with_ref(f) self.to_c_str().with_ref(f)
} }
} }
unsafe fn with_c_str_unchecked<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
if self.len() < BUF_LEN {
do self.as_imm_buf |self_buf, self_len| {
let mut buf: [u8, .. BUF_LEN] = intrinsics::uninit();
do buf.as_mut_buf |buf, _| {
ptr::copy_memory(buf, self_buf, self_len);
*ptr::mut_offset(buf, self_len as int) = 0;
f(buf as *libc::c_char)
}
}
} else {
self.to_c_str().with_ref(f)
}
}
} }
#[inline] #[inline]
@ -616,4 +638,29 @@ mod bench {
fn bench_with_c_str_long(bh: &mut BenchHarness) { fn bench_with_c_str_long(bh: &mut BenchHarness) {
bench_with_c_str(bh, s_long) bench_with_c_str(bh, s_long)
} }
fn bench_with_c_str_unchecked(bh: &mut BenchHarness, s: &str) {
do bh.iter {
unsafe {
do s.with_c_str_unchecked |c_str_buf| {
check(s, c_str_buf)
}
}
}
}
#[bench]
fn bench_with_c_str_unchecked_short(bh: &mut BenchHarness) {
bench_with_c_str_unchecked(bh, s_short)
}
#[bench]
fn bench_with_c_str_unchecked_medium(bh: &mut BenchHarness) {
bench_with_c_str_unchecked(bh, s_medium)
}
#[bench]
fn bench_with_c_str_unchecked_long(bh: &mut BenchHarness) {
bench_with_c_str_unchecked(bh, s_long)
}
} }