diff options
| author | bors <bors@rust-lang.org> | 2013-05-29 13:29:06 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-05-29 13:29:06 -0700 |
| commit | 35655a0fb3bde60985d5f92437a729c37bb8755a (patch) | |
| tree | c53e8472af7f1d44e1d584654ec28135ea6050fb /src/libstd | |
| parent | d2957091c496be86fe4b648a0ccae08753122661 (diff) | |
| parent | 3141acf674fd34f66141c4659a4a239779bb2802 (diff) | |
| download | rust-35655a0fb3bde60985d5f92437a729c37bb8755a.tar.gz rust-35655a0fb3bde60985d5f92437a729c37bb8755a.zip | |
auto merge of #6803 : Thiez/rust/native_fmax_fmin, r=brson
Calls to the libc versions of fmin and fmax were relatively slow (perhaps because they could not be inlined?). This pull request provides f32 and f64 with fmin and fmax written in Rust, and shows a significant speed increase on my system; I used https://github.com/thiez/rustray as my benchmark, with --opt-level 3 it brings the ray-tracing time down from 10.8 seconds to about 9.2, which seemed significant to me. r?
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/num/f32.rs | 12 | ||||
| -rw-r--r-- | src/libstd/num/f64.rs | 11 |
2 files changed, 19 insertions, 4 deletions
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 94cff78375a..b578084268a 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -86,8 +86,6 @@ delegate!( fn erfc(n: c_float) -> c_float = c_float_utils::erfc, fn exp_m1(n: c_float) -> c_float = c_float_utils::exp_m1, fn abs_sub(a: c_float, b: c_float) -> c_float = c_float_utils::abs_sub, - fn fmax(a: c_float, b: c_float) -> c_float = c_float_utils::fmax, - fn fmin(a: c_float, b: c_float) -> c_float = c_float_utils::fmin, fn next_after(x: c_float, y: c_float) -> c_float = c_float_utils::next_after, fn frexp(n: c_float, value: &mut c_int) -> c_float = c_float_utils::frexp, fn hypot(x: c_float, y: c_float) -> c_float = c_float_utils::hypot, @@ -147,6 +145,16 @@ pub fn ge(x: f32, y: f32) -> bool { return x >= y; } #[inline(always)] pub fn gt(x: f32, y: f32) -> bool { return x > y; } +#[inline(always)] +pub fn fmax(x: f32, y: f32) -> f32 { + if x >= y || y.is_NaN() { x } else { y } +} + +#[inline(always)] +pub fn fmin(x: f32, y: f32) -> f32 { + if x <= y || y.is_NaN() { x } else { y } +} + // FIXME (#1999): replace the predicates below with llvm intrinsics or // calls to the libmath macros in the rust runtime for performance. diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index b7754ed07ad..bca730c5748 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -87,8 +87,6 @@ delegate!( fn erfc(n: c_double) -> c_double = c_double_utils::erfc, fn exp_m1(n: c_double) -> c_double = c_double_utils::exp_m1, fn abs_sub(a: c_double, b: c_double) -> c_double = c_double_utils::abs_sub, - fn fmax(a: c_double, b: c_double) -> c_double = c_double_utils::fmax, - fn fmin(a: c_double, b: c_double) -> c_double = c_double_utils::fmin, fn next_after(x: c_double, y: c_double) -> c_double = c_double_utils::next_after, fn frexp(n: c_double, value: &mut c_int) -> c_double = c_double_utils::frexp, fn hypot(x: c_double, y: c_double) -> c_double = c_double_utils::hypot, @@ -172,6 +170,15 @@ pub fn ge(x: f64, y: f64) -> bool { return x >= y; } #[inline(always)] pub fn gt(x: f64, y: f64) -> bool { return x > y; } +#[inline(always)] +pub fn fmax(x: f64, y: f64) -> f64 { + if x >= y || y.is_NaN() { x } else { y } +} + +#[inline(always)] +pub fn fmin(x: f64, y: f64) -> f64 { + if x <= y || y.is_NaN() { x } else { y } +} // FIXME (#1999): add is_normal, is_subnormal, and fpclassify |
