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

ruby-changes:15192

From: akr <ko1@a...>
Date: Sun, 28 Mar 2010 08:24:38 +0900 (JST)
Subject: [ruby-changes:15192] Ruby:r27072 (trunk): * time.c (weq): optimize for small integer.

akr	2010-03-28 08:24:20 +0900 (Sun, 28 Mar 2010)

  New Revision: 27072

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=27072

  Log:
    * time.c (weq): optimize for small integer.
      (wne): ditto.
      (wlt): ditto.
      (wgt): ditto.
      (wle): ditto.
      (wge): ditto.
      (rb_time_magnify): ditto.
      (rb_time_unmagnify): ditto.
      (rb_time_unmagnify_to_float): new function to avoid rational for
      Time#to_f and Time#-.

  Modified files:
    trunk/ChangeLog
    trunk/time.c

Index: time.c
===================================================================
--- time.c	(revision 27071)
+++ time.c	(revision 27072)
@@ -325,13 +325,33 @@
     *r = rb_ary_entry(ary, 1);
 }
 
-#define weq(x,y) (RTEST(rb_funcall(w2xv(x), id_eq, 1, w2xv(y))))
-#define wne(x,y) (RTEST(rb_funcall(w2xv(x), id_ne, 1, w2xv(y))))
-#define wlt(x,y) (RTEST(rb_funcall(w2xv(x), '<', 1, w2xv(y))))
-#define wgt(x,y) (RTEST(rb_funcall(w2xv(x), '>', 1, w2xv(y))))
-#define wle(x,y) (!gt(w2xv(x),w2xv(y)))
-#define wge(x,y) (!lt(w2xv(x),w2xv(y)))
+static int
+weq(timew_t wx, timew_t wy)
+{
+#if TIMEVALUE_IS_UINT64
+    if (FIXTV_P(TIMEW_GETVAL(wx)) && FIXTV_P(TIMEW_GETVAL(wy))) {
+        return FIXTVtoINT64(TIMEW_GETVAL(wx)) == FIXTVtoINT64(TIMEW_GETVAL(wy));
+    }
+#endif
+    return RTEST(rb_funcall(w2xv(wx), id_eq, 1, w2xv(wy)));
+}
 
+static int
+wlt(timew_t wx, timew_t wy)
+{
+#if TIMEVALUE_IS_UINT64
+    if (FIXTV_P(TIMEW_GETVAL(wx)) && FIXTV_P(TIMEW_GETVAL(wy))) {
+        return FIXTVtoINT64(TIMEW_GETVAL(wx)) < FIXTVtoINT64(TIMEW_GETVAL(wy));
+    }
+#endif
+    return RTEST(rb_funcall(w2xv(wx), '<', 1, w2xv(wy)));
+}
+
+#define wne(x,y) (!weq(x,y))
+#define wgt(x,y) (wlt(y,x))
+#define wle(x,y) (!wgt(x,y))
+#define wge(x,y) (!wlt(x,y))
+
 static timew_t
 wadd(timew_t wx, timew_t wy)
 {
@@ -565,16 +585,68 @@
 static timew_t
 rb_time_magnify(VALUE v)
 {
+    timew_t ret;
+    if (FIXNUM_P(v)) {
+#if TIMEVALUE_IS_UINT64 && SIZEOF_LONG * 2 <= SIZEOF_INT64_T
+        int64_t i64 = (int64_t)FIX2LONG(v) * TIME_SCALE;
+        TIMEW_SETVAL(ret, INT64toFIXTV(i64));
+        return ret;
+#else
+        long a, b, c;
+        a = FIX2LONG(v);
+        if (a == 0)
+            return x;
+        b = TIME_SCALE;
+        c = a * b;
+        if (c / a == b) {
+            TIMEW_SETVAL(ret, INT64toFIXTV(c));
+            return ret;
+        }
+#endif
+    }
     return xv2w(mul(v, INT2FIX(TIME_SCALE)));
 }
 
 static VALUE
 rb_time_unmagnify(timew_t w)
 {
-    VALUE v = w2xv(w);
+    VALUE v;
+#if TIMEVALUE_IS_UINT64
+    if (FIXTV_P(TIMEW_GETVAL(w))) {
+      int64_t a, b, c;
+      a = FIXTVtoINT64(TIMEW_GETVAL(w));
+      b = TIME_SCALE;
+      c = a / b;
+      if (c * b == a) {
+          return INT64toNUM(c);
+      }
+    }
+#endif
+    v = w2xv(w);
     return quo(v, INT2FIX(TIME_SCALE));
 }
 
+static VALUE
+rb_time_unmagnify_to_float(timew_t w)
+{
+    VALUE v;
+#if TIMEVALUE_IS_UINT64
+    if (FIXTV_P(TIMEW_GETVAL(w))) {
+        int64_t a, b, c;
+        a = FIXTVtoINT64(TIMEW_GETVAL(w));
+        b = TIME_SCALE;
+        c = a / b;
+        if (c * b == a) {
+            return DBL2NUM((double)c);
+        }
+        v = DBL2NUM(FIXTVtoINT64(TIMEW_GETVAL(w)));
+        return quo(v, DBL2NUM(TIME_SCALE));
+    }
+#endif
+    v = w2xv(w);
+    return quo(v, DBL2NUM(TIME_SCALE));
+}
+
 static const int common_year_yday_offset[] = {
     -1,
     -1 + 31,
@@ -651,8 +723,8 @@
     vdays = LONG2NUM(days_in400);
     vdays = add(vdays, mul(q400, INT2FIX(97)));
     vdays = add(vdays, mul(year1900, INT2FIX(365)));
-    ret = add(ret, mul(vdays, INT2FIX(86400)));
-    wret = wadd(rb_time_magnify(ret), xv2w(vtm->subsecx));
+    wret = wadd(rb_time_magnify(ret), wmul(rb_time_magnify(vdays), xv2w(INT2FIX(86400))));
+    wret = wadd(wret, xv2w(vtm->subsecx));
 
     return wret;
 }
@@ -999,7 +1071,7 @@
 
     init_leap_second_info();
 
-    if (wlt(rb_time_magnify(LONG2NUM(known_leap_seconds_limit)), timew)) {
+    if (wlt(TIMET2TIMEW(known_leap_seconds_limit), timew)) {
         timew = wsub(timew, rb_time_magnify(INT2NUM(number_of_leap_seconds_known)));
         gmtimew_noleapsecond(timew, result);
         return result;
@@ -2743,7 +2815,7 @@
     struct time_object *tobj;
 
     GetTimeval(time, tobj);
-    return rb_Float(rb_time_unmagnify(tobj->timew));
+    return rb_Float(rb_time_unmagnify_to_float(tobj->timew));
 }
 
 /*
@@ -3305,7 +3377,7 @@
 	struct time_object *tobj2;
 
 	GetTimeval(time2, tobj2);
-        return rb_Float(rb_time_unmagnify(wsub(tobj->timew, tobj2->timew)));
+        return rb_Float(rb_time_unmagnify_to_float(wsub(tobj->timew, tobj2->timew)));
     }
     return time_add(tobj, time2, -1);
 }
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 27071)
+++ ChangeLog	(revision 27072)
@@ -1,3 +1,16 @@
+Sun Mar 28 08:20:37 2010  Tanaka Akira  <akr@f...>
+
+	* time.c (weq): specialize for small integer.
+	  (wne): ditto.
+	  (wlt): ditto.
+	  (wgt): ditto.
+	  (wle): ditto.
+	  (wge): ditto.
+	  (rb_time_magnify): ditto.
+	  (rb_time_unmagnify): ditto.
+	  (rb_time_unmagnify_to_float): new function to avoid rational for
+	  Time#to_f and Time#-.
+
 Sun Mar 28 07:12:41 2010  Tanaka Akira  <akr@f...>
 
 	* time.c (mul): condition refined.

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

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