[前][次][番号順一覧][スレッド一覧]

ruby-changes:44646

From: mrkn <ko1@a...>
Date: Sat, 12 Nov 2016 00:55:36 +0900 (JST)
Subject: [ruby-changes:44646] mrkn:r56719 (trunk): rational.c: avoid needless object allocation with nurat_to_double

mrkn	2016-11-12 00:55:30 +0900 (Sat, 12 Nov 2016)

  New Revision: 56719

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56719

  Log:
    rational.c: avoid needless object allocation with nurat_to_double
    
    * rational.c (nurat_to_double): introduce to convert rational to double
      without object allocation.
    
    * rational.c (rb_rational_plus, nurat_{sub,mul,to_f}): rewrite by using
      nurat_to_double.
    
    * bignum.c (rb_big_fdiv_double): introduce to calculate fdiv and return
      the result as a double value.
    
    * bignum.c (big_fdiv{,_int,_float}): change the return types for
      implementing rb_big_fdiv_double.
    
    * bignum.c (rb_big_fdiv): rewrite by using rb_big_fdiv_double.
    
    * numeric.c (rb_int_fdiv_double): introduce to calculate fdiv and return
      the result as a double value.
    
    * numeric.c (fix_fdiv_double): rewrite from fix_fdiv to return the
      result as a double value.
    
    * numeric.c (rb_int_fdiv): rewrite by using rb_int_fdiv_double.
    
    * internal.h (rb_{big,int}_fdiv_double): exported.

  Modified files:
    trunk/bignum.c
    trunk/internal.h
    trunk/numeric.c
    trunk/rational.c
Index: internal.h
===================================================================
--- internal.h	(revision 56718)
+++ internal.h	(revision 56719)
@@ -891,7 +891,7 @@ size_t rb_ary_memsize(VALUE); https://github.com/ruby/ruby/blob/trunk/internal.h#L891
 
 /* bignum.c */
 extern const char ruby_digitmap[];
-VALUE rb_big_fdiv(VALUE x, VALUE y);
+double rb_big_fdiv_double(VALUE x, VALUE y);
 VALUE rb_big_uminus(VALUE x);
 VALUE rb_big_hash(VALUE);
 VALUE rb_big_odd_p(VALUE);
@@ -1170,7 +1170,7 @@ VALUE rb_dbl_hash(double d); https://github.com/ruby/ruby/blob/trunk/internal.h#L1170
 VALUE rb_fix_plus(VALUE x, VALUE y);
 VALUE rb_int_ge(VALUE x, VALUE y);
 enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts);
-VALUE rb_int_fdiv(VALUE x, VALUE y);
+double rb_int_fdiv_double(VALUE x, VALUE y);
 
 #if USE_FLONUM
 #define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))
Index: numeric.c
===================================================================
--- numeric.c	(revision 56718)
+++ numeric.c	(revision 56719)
@@ -3549,6 +3549,35 @@ rb_int_mul(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L3549
     return rb_num_coerce_bin(x, y, '*');
 }
 
+static double
+fix_fdiv_double(VALUE x, VALUE y)
+{
+    if (FIXNUM_P(y)) {
+        return (double)FIX2LONG(x) / (double)FIX2LONG(y);
+    }
+    else if (RB_TYPE_P(y, T_BIGNUM)) {
+        return rb_big_fdiv_double(rb_int2big(FIX2LONG(x)), y);
+    }
+    else if (RB_TYPE_P(y, T_FLOAT)) {
+        return (double)FIX2LONG(x) / RFLOAT_VALUE(y);
+    }
+    else {
+        return RFLOAT_VALUE(rb_num_coerce_bin(x, y, rb_intern("fdiv")));
+    }
+}
+
+double
+rb_int_fdiv_double(VALUE x, VALUE y)
+{
+    if (FIXNUM_P(x)) {
+        return fix_fdiv_double(x, y);
+    }
+    else if (RB_TYPE_P(x, T_BIGNUM)) {
+        return rb_big_fdiv_double(x, y);
+    }
+    return NAN;
+}
+
 /*
  *  Document-method: Integer#fdiv
  *  call-seq:
@@ -3564,31 +3593,11 @@ rb_int_mul(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L3593
  *
  */
 
-static VALUE
-fix_fdiv(VALUE x, VALUE y)
-{
-    if (FIXNUM_P(y)) {
-	return DBL2NUM((double)FIX2LONG(x) / (double)FIX2LONG(y));
-    }
-    else if (RB_TYPE_P(y, T_BIGNUM)) {
-	return rb_big_fdiv(rb_int2big(FIX2LONG(x)), y);
-    }
-    else if (RB_TYPE_P(y, T_FLOAT)) {
-	return DBL2NUM((double)FIX2LONG(x) / RFLOAT_VALUE(y));
-    }
-    else {
-	return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
-    }
-}
-
 VALUE
 rb_int_fdiv(VALUE x, VALUE y)
 {
-    if (FIXNUM_P(x)) {
-	return fix_fdiv(x, y);
-    }
-    else if (RB_TYPE_P(x, T_BIGNUM)) {
-	return rb_big_fdiv(x, y);
+    if (RB_INTEGER_TYPE_P(x)) {
+        return DBL2NUM(rb_int_fdiv_double(x, y));
     }
     return Qnil;
 }
Index: rational.c
===================================================================
--- rational.c	(revision 56718)
+++ rational.c	(revision 56719)
@@ -721,7 +721,7 @@ f_addsub(VALUE self, VALUE anum, VALUE a https://github.com/ruby/ruby/blob/trunk/rational.c#L721
     return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
 }
 
-static VALUE nurat_to_f(VALUE self);
+static double nurat_to_double(VALUE self);
 /*
  * call-seq:
  *    rat + numeric  ->  numeric
@@ -747,7 +747,7 @@ rb_rational_plus(VALUE self, VALUE other https://github.com/ruby/ruby/blob/trunk/rational.c#L747
 	}
     }
     else if (RB_TYPE_P(other, T_FLOAT)) {
-	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) + RFLOAT_VALUE(other));
+	return DBL2NUM(nurat_to_double(self) + RFLOAT_VALUE(other));
     }
     else if (RB_TYPE_P(other, T_RATIONAL)) {
 	{
@@ -788,7 +788,7 @@ nurat_sub(VALUE self, VALUE other) https://github.com/ruby/ruby/blob/trunk/rational.c#L788
 	}
     }
     else if (RB_FLOAT_TYPE_P(other)) {
-	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) - RFLOAT_VALUE(other));
+	return DBL2NUM(nurat_to_double(self) - RFLOAT_VALUE(other));
     }
     else if (RB_TYPE_P(other, T_RATIONAL)) {
 	{
@@ -868,7 +868,7 @@ nurat_mul(VALUE self, VALUE other) https://github.com/ruby/ruby/blob/trunk/rational.c#L868
 	}
     }
     else if (RB_FLOAT_TYPE_P(other)) {
-	return DBL2NUM(RFLOAT_VALUE(nurat_to_f(self)) * RFLOAT_VALUE(other));
+	return DBL2NUM(nurat_to_double(self) * RFLOAT_VALUE(other));
     }
     else if (RB_TYPE_P(other, T_RATIONAL)) {
 	{
@@ -1433,6 +1433,13 @@ nurat_round_n(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/rational.c#L1433
     return f_round_common(argc, argv, self, round_func);
 }
 
+static double
+nurat_to_double(VALUE self)
+{
+    get_dat1(self);
+    return rb_int_fdiv_double(dat->num, dat->den);
+}
+
 /*
  * call-seq:
  *    rat.to_f  ->  float
@@ -1447,8 +1454,7 @@ nurat_round_n(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/rational.c#L1454
 static VALUE
 nurat_to_f(VALUE self)
 {
-    get_dat1(self);
-    return rb_int_fdiv(dat->num, dat->den);
+    return DBL2NUM(nurat_to_double(self));
 }
 
 /*
Index: bignum.c
===================================================================
--- bignum.c	(revision 56718)
+++ bignum.c	(revision 56719)
@@ -6090,7 +6090,7 @@ big_shift(VALUE x, long n) https://github.com/ruby/ruby/blob/trunk/bignum.c#L6090
     return x;
 }
 
-static VALUE
+static double
 big_fdiv(VALUE x, VALUE y, long ey)
 {
 #define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)
@@ -6108,14 +6108,14 @@ big_fdiv(VALUE x, VALUE y, long ey) https://github.com/ruby/ruby/blob/trunk/bignum.c#L6108
 #if SIZEOF_LONG > SIZEOF_INT
     {
 	/* Visual C++ can't be here */
-	if (l > INT_MAX) return DBL2NUM(INFINITY);
-	if (l < INT_MIN) return DBL2NUM(0.0);
+	if (l > INT_MAX) return INFINITY;
+	if (l < INT_MIN) return 0.0;
     }
 #endif
-    return DBL2NUM(ldexp(big2dbl(z), (int)l));
+    return ldexp(big2dbl(z), (int)l);
 }
 
-static VALUE
+static double
 big_fdiv_int(VALUE x, VALUE y)
 {
     long l, ey;
@@ -6127,7 +6127,7 @@ big_fdiv_int(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L6127
     return big_fdiv(x, y, ey);
 }
 
-static VALUE
+static double
 big_fdiv_float(VALUE x, VALUE y)
 {
     int i;
@@ -6135,8 +6135,8 @@ big_fdiv_float(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L6135
     return big_fdiv(x, y, i - DBL_MANT_DIG);
 }
 
-VALUE
-rb_big_fdiv(VALUE x, VALUE y)
+double
+rb_big_fdiv_double(VALUE x, VALUE y)
 {
     double dx, dy;
 
@@ -6154,14 +6154,20 @@ rb_big_fdiv(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L6154
     else if (RB_FLOAT_TYPE_P(y)) {
 	dy = RFLOAT_VALUE(y);
 	if (isnan(dy))
-	    return y;
+	    return dy;
 	if (isinf(dx))
 	    return big_fdiv_float(x, y);
     }
     else {
-	return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
+	return RFLOAT_VALUE(rb_num_coerce_bin(x, y, rb_intern("fdiv")));
     }
-    return DBL2NUM(dx / dy);
+    return dx / dy;
+}
+
+VALUE
+rb_big_fdiv(VALUE x, VALUE y)
+{
+    return DBL2NUM(rb_big_fdiv_double(x, y));
 }
 
 VALUE

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]