about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-05-29 13:29:06 -0700
committerbors <bors@rust-lang.org>2013-05-29 13:29:06 -0700
commit35655a0fb3bde60985d5f92437a729c37bb8755a (patch)
treec53e8472af7f1d44e1d584654ec28135ea6050fb /src/libstd
parentd2957091c496be86fe4b648a0ccae08753122661 (diff)
parent3141acf674fd34f66141c4659a4a239779bb2802 (diff)
downloadrust-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.rs12
-rw-r--r--src/libstd/num/f64.rs11
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