1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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#-.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27072 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2010-03-27 23:24:20 +00:00
parent 075cbd2ad6
commit 86aa8f3f0f
2 changed files with 97 additions and 12 deletions

View file

@ -1,3 +1,16 @@
Sun Mar 28 08:20:37 2010 Tanaka Akira <akr@fsij.org>
* 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@fsij.org>
* time.c (mul): condition refined.

96
time.c
View file

@ -325,12 +325,32 @@ divmodv(VALUE n, VALUE d, VALUE *q, VALUE *r)
*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 @@ num_exact(VALUE v)
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 @@ timegmw_noleapsecond(struct vtm *vtm)
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 @@ gmtimew(timew_t timew, struct vtm *result)
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 @@ time_to_f(VALUE time)
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 @@ time_minus(VALUE time1, VALUE time2)
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);
}