From df445b470e9b9169c793019c51b834e186526b15 Mon Sep 17 00:00:00 2001 From: nobu Date: Fri, 30 Jan 2015 08:28:32 +0000 Subject: math.c: optimization for Bignum * math.c (num2dbl_with_to_f): make faster when Bignum passed by direct conversion using rb_big2dbl(). [Feature #10800] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49449 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- math.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'math.c') diff --git a/math.c b/math.c index 3f0b11e344..5d4c2bbea5 100644 --- a/math.c +++ b/math.c @@ -26,13 +26,38 @@ static ID id_to_f; VALUE rb_mMath; VALUE rb_eMathDomainError; -#define fix_to_f_optimizable() rb_method_basic_definition_p(rb_cFixnum, id_to_f) -#define Get_Float(x) \ - ((RB_TYPE_P((x), T_FLOAT) ? (void)0 : ((x) = rb_to_float(x))), RFLOAT_VALUE(x)) -#define Get_Double(x) \ - (FIXNUM_P(x) && fix_to_f_optimizable() ? \ - (double)FIX2LONG(x) : \ - Get_Float(x)) +static inline int +basic_to_f_p(VALUE klass) +{ + return rb_method_basic_definition_p(klass, id_to_f); +} + +static inline double +num2dbl_with_to_f(VALUE num) +{ + if (SPECIAL_CONST_P(num)) { + if (FIXNUM_P(num)) { + if (basic_to_f_p(rb_cFixnum)) + return (double)FIX2LONG(num); + } + else if (FLONUM_P(num)) { + return RFLOAT_VALUE(num); + } + } + else { + switch (BUILTIN_TYPE(num)) { + case T_FLOAT: + return RFLOAT_VALUE(num); + case T_BIGNUM: + if (basic_to_f_p(rb_cBignum)) + return rb_big2dbl(num); + break; + } + } + return RFLOAT_VALUE(rb_to_float(num)); +} + +#define Get_Double(x) num2dbl_with_to_f(x) #define domain_error(msg) \ rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg) -- cgit v1.2.3