summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-30 04:01:42 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-30 04:01:42 +0000
commitdcf2aad3a588f75e21bc22c269d652e5b8255672 (patch)
tree6ddc088959c79044887d6aab02e88ed48755ac6e
parent570d8f55b225dce01008c8fa879e85ad874ce18b (diff)
* time.c (add): shortcut implemented for fixnums.
(sub): ditto. (mul): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24710 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--time.c36
2 files changed, 33 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 1c364af085..c5014e983a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sun Aug 30 13:00:11 2009 Tanaka Akira <akr@fsij.org>
+
+ * time.c (add): shortcut implemented for fixnums.
+ (sub): ditto.
+ (mul): ditto.
+
Sun Aug 30 10:24:43 2009 Tanaka Akira <akr@fsij.org>
* time.c (eq): apply RTEST.
diff --git a/time.c b/time.c
index bc2e769491..8a680c9f15 100644
--- a/time.c
+++ b/time.c
@@ -116,28 +116,46 @@ static ID id_eq, id_ne, id_quo, id_div, id_cmp, id_lshift;
static VALUE
add(VALUE x, VALUE y)
{
- switch (TYPE(x)) {
- case T_BIGNUM: return rb_big_plus(x, y);
- default: return rb_funcall(x, '+', 1, y);
+ if (FIXNUM_P(x) && FIXNUM_P(y)) {
+ long l = FIX2LONG(x) + FIX2LONG(y);
+ if (FIXABLE(l)) return LONG2FIX(l);
+ return LONG2NUM(l);
}
+ if (TYPE(x) == T_BIGNUM) return rb_big_plus(x, y);
+ return rb_funcall(x, '+', 1, y);
}
static VALUE
sub(VALUE x, VALUE y)
{
- switch (TYPE(x)) {
- case T_BIGNUM: return rb_big_minus(x, y);
- default: return rb_funcall(x, '-', 1, y);
+ if (FIXNUM_P(x) && FIXNUM_P(y)) {
+ long l = FIX2LONG(x) - FIX2LONG(y);
+ if (FIXABLE(l)) return LONG2FIX(l);
+ return LONG2NUM(l);
}
+ if (TYPE(x) == T_BIGNUM) return rb_big_minus(x, y);
+ return rb_funcall(x, '-', 1, y);
}
static VALUE
mul(VALUE x, VALUE y)
{
- switch (TYPE(x)) {
- case T_BIGNUM: return rb_big_mul(x, y);
- default: return rb_funcall(x, '*', 1, y);
+ if (FIXNUM_P(x) && FIXNUM_P(y)) {
+#if HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
+ LONG_LONG ll = (LONG_LONG)FIX2LONG(x) * FIX2LONG(y);
+ if (FIXABLE(ll)) return LONG2FIX(ll);
+ return LL2NUM(ll);
+#else
+ long a, b, c;
+ a = FIX2LONG(x);
+ if (a == 0) return x;
+ b = FIX2LONG(y);
+ c = a * b;
+ if (c / a == b && FIXABLE(c)) return LONG2FIX(c);
+#endif
}
+ if (TYPE(x) == T_BIGNUM) return rb_big_mul(x, y);
+ return rb_funcall(x, '*', 1, y);
}
#define div(x,y) (rb_funcall((x), id_div, 1, (y)))