auto merge of #14216 : kballard/rust/macos_precise_time_ns, r=alexcrichton
Use sync:1️⃣: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.
This commit is contained in:
commit
2216eceea5
@ -83,7 +83,7 @@ DEPS_fourcc := syntax std
|
|||||||
DEPS_hexfloat := syntax std
|
DEPS_hexfloat := syntax std
|
||||||
DEPS_num := std rand
|
DEPS_num := std rand
|
||||||
DEPS_test := std collections getopts serialize term time regex
|
DEPS_test := std collections getopts serialize term time regex
|
||||||
DEPS_time := std serialize
|
DEPS_time := std serialize sync
|
||||||
DEPS_rand := std
|
DEPS_rand := std
|
||||||
DEPS_url := std collections
|
DEPS_url := std collections
|
||||||
DEPS_workcache := std serialize collections log
|
DEPS_workcache := std serialize collections log
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
extern crate sync;
|
||||||
|
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::num;
|
use std::num;
|
||||||
@ -159,10 +161,16 @@ pub fn precise_time_ns() -> u64 {
|
|||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn os_precise_time_ns() -> u64 {
|
fn os_precise_time_ns() -> u64 {
|
||||||
let time = unsafe { imp::mach_absolute_time() };
|
static mut TIMEBASE: libc::mach_timebase_info = libc::mach_timebase_info { numer: 0,
|
||||||
let mut info = libc::mach_timebase_info { numer: 0, denom: 0 };
|
denom: 0 };
|
||||||
unsafe { imp::mach_timebase_info(&mut info); }
|
static mut ONCE: sync::one::Once = sync::one::ONCE_INIT;
|
||||||
return time * ((info.numer / info.denom) as u64);
|
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"))]
|
#[cfg(not(windows), not(target_os = "macos"))]
|
||||||
@ -1080,11 +1088,13 @@ pub fn strftime(format: &str, tm: &Tm) -> StrBuf {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
extern crate test;
|
||||||
use super::{Timespec, get_time, precise_time_ns, precise_time_s, tzset,
|
use super::{Timespec, get_time, precise_time_ns, precise_time_s, tzset,
|
||||||
at_utc, at, strptime};
|
at_utc, at, strptime};
|
||||||
|
|
||||||
use std::f64;
|
use std::f64;
|
||||||
use std::result::{Err, Ok};
|
use std::result::{Err, Ok};
|
||||||
|
use self::test::Bencher;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn set_time_zone() {
|
fn set_time_zone() {
|
||||||
@ -1520,4 +1530,9 @@ mod tests {
|
|||||||
test_strftime();
|
test_strftime();
|
||||||
test_timespec_eq_ord();
|
test_timespec_eq_ord();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_precise_time_ns(b: &mut Bencher) {
|
||||||
|
b.iter(|| precise_time_ns())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user