Skip to content

Commit

Permalink
auto merge of #14216 : kballard/rust/macos_precise_time_ns, r=alexcri…
Browse files Browse the repository at this point in the history
…chton

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.
  • Loading branch information
bors committed May 16, 2014
2 parents cea4803 + 8ef3e22 commit 2216ece
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
2 changes: 1 addition & 1 deletion mk/crates.mk
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ DEPS_fourcc := syntax std
DEPS_hexfloat := syntax std
DEPS_num := std rand
DEPS_test := std collections getopts serialize term time regex
DEPS_time := std serialize
DEPS_time := std serialize sync
DEPS_rand := std
DEPS_url := std collections
DEPS_workcache := std serialize collections log
Expand Down
23 changes: 19 additions & 4 deletions src/libtime/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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"))]
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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())
}
}

0 comments on commit 2216ece

Please sign in to comment.