diff options
| author | bors <bors@rust-lang.org> | 2014-05-16 16:31:24 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-05-16 16:31:24 -0700 |
| commit | 2216eceea51b344560f4791336b3ea2c897eec39 (patch) | |
| tree | 231d3f6640253dc2371426efe5ea67ff53b8d226 /src/libtime | |
| parent | cea4803d4cf56ded65be6a9e043a6219c661c572 (diff) | |
| parent | 8ef3e227198f6ff674b1626d0862c4112358c1a1 (diff) | |
auto merge of #14216 : kballard/rust/macos_precise_time_ns, r=alexcrichton
Use sync::one::Once to fetch the mach_timebase_info only once when running precise_time_ns(). This helps because mach_timebase_info() is surprisingly inefficient. Also fix the order of operations when applying the timebase to the mach absolute time value. This improves the time on my machine from ``` test tests::bench_precise_time_ns ... bench: 157 ns/iter (+/- 4) ``` to ``` test tests::bench_precise_time_ns ... bench: 38 ns/iter (+/- 3) ``` and it will get even faster once #14174 lands.
Diffstat (limited to 'src/libtime')
| -rw-r--r-- | src/libtime/lib.rs | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs index b580626c9c3..0e67076dc08 100644 --- a/src/libtime/lib.rs +++ b/src/libtime/lib.rs @@ -24,6 +24,8 @@ #[cfg(test)] #[phase(syntax, link)] extern crate log; extern crate serialize; extern crate libc; +#[cfg(target_os = "macos")] +extern crate sync; use std::io::BufReader; use std::num; @@ -159,10 +161,16 @@ pub fn precise_time_ns() -> u64 { #[cfg(target_os = "macos")] fn os_precise_time_ns() -> u64 { - let time = unsafe { imp::mach_absolute_time() }; - let mut info = libc::mach_timebase_info { numer: 0, denom: 0 }; - unsafe { imp::mach_timebase_info(&mut info); } - return time * ((info.numer / info.denom) as u64); + static mut TIMEBASE: libc::mach_timebase_info = libc::mach_timebase_info { numer: 0, + denom: 0 }; + static mut ONCE: sync::one::Once = sync::one::ONCE_INIT; + unsafe { + ONCE.doit(|| { + imp::mach_timebase_info(&mut TIMEBASE); + }); + let time = imp::mach_absolute_time(); + time * TIMEBASE.numer as u64 / TIMEBASE.denom as u64 + } } #[cfg(not(windows), not(target_os = "macos"))] @@ -1080,11 +1088,13 @@ pub fn strftime(format: &str, tm: &Tm) -> StrBuf { #[cfg(test)] mod tests { + extern crate test; use super::{Timespec, get_time, precise_time_ns, precise_time_s, tzset, at_utc, at, strptime}; use std::f64; use std::result::{Err, Ok}; + use self::test::Bencher; #[cfg(windows)] fn set_time_zone() { @@ -1520,4 +1530,9 @@ mod tests { test_strftime(); test_timespec_eq_ord(); } + + #[bench] + fn bench_precise_time_ns(b: &mut Bencher) { + b.iter(|| precise_time_ns()) + } } |
