ruby-changes:46806
From: watson1978 <ko1@a...>
Date: Sat, 27 May 2017 14:41:06 +0900 (JST)
Subject: [ruby-changes:46806] watson1978:r58921 (trunk): Improve performance of some Time methods
watson1978 2017-05-27 14:41:00 +0900 (Sat, 27 May 2017) New Revision: 58921 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=58921 Log: Improve performance of some Time methods internal.h : add rb_numeric_quo() as internal API. rational.c : rename numeric_quo() to rb_numeric_quo() as internal API. time.c (quov): optimize by invoking rb_numeric_quo() to retrieve a value of Numeric#quo instead of method dispatching via rb_funcall(). Time#subsec -> 7 % up Time#- -> 26 % up Time#to_f -> 30 % up Time#to_r -> 7 % up [ruby-core:80915] [Bug #13519] [Fix GH-1601] ### Before Time#subsec 2.024M (?\194?\177 8.7%) i/s - 10.062M in 5.009762s Time#- 5.049M (?\194?\177 4.7%) i/s - 25.186M in 5.002379s Time#to_f 5.625M (?\194?\177 4.2%) i/s - 28.066M in 5.000749s Time#to_r 1.880M (?\194?\177 9.7%) i/s - 9.361M in 5.027527s ### After Time#subsec 2.155M (?\194?\177 9.7%) i/s - 10.724M in 5.022579s Time#- 6.362M (?\194?\177 2.0%) i/s - 31.824M in 5.004625s Time#to_f 7.287M (?\194?\177 4.8%) i/s - 36.402M in 5.010983s Time#to_r 2.020M (?\194?\177 9.4%) i/s - 10.059M in 5.021852s ### Test code require 'benchmark/ips' Benchmark.ips do |x| x.report "Time#subsec" do |t| time = Time.now t.times { time.subsec } end x.report "Time#-" do |t| time1 = Time.now time2 = Time.now t.times { time1 - time2 } end x.report "Time#to_f" do |t| time = Time.now t.times { time.to_f } end x.report "Time#to_r" do |t| time = Time.now t.times { time.to_r } end end Modified files: trunk/internal.h trunk/rational.c trunk/time.c Index: internal.h =================================================================== --- internal.h (revision 58920) +++ internal.h (revision 58921) @@ -1540,6 +1540,7 @@ VALUE rb_rational_reciprocal(VALUE x); https://github.com/ruby/ruby/blob/trunk/internal.h#L1540 VALUE rb_cstr_to_rat(const char *, int); VALUE rb_rational_abs(VALUE self); VALUE rb_rational_cmp(VALUE self, VALUE other); +VALUE rb_numeric_quo(VALUE x, VALUE y); /* re.c */ VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline); Index: rational.c =================================================================== --- rational.c (revision 58920) +++ rational.c (revision 58921) @@ -2015,8 +2015,8 @@ numeric_denominator(VALUE self) https://github.com/ruby/ruby/blob/trunk/rational.c#L2015 * Returns the most exact division (rational for integers, float for floats). */ -static VALUE -numeric_quo(VALUE x, VALUE y) +VALUE +rb_numeric_quo(VALUE x, VALUE y) { if (RB_FLOAT_TYPE_P(y)) { return rb_funcall(x, rb_intern("fdiv"), 1, y); @@ -2736,7 +2736,7 @@ Init_Rational(void) https://github.com/ruby/ruby/blob/trunk/rational.c#L2736 rb_define_method(rb_cNumeric, "numerator", numeric_numerator, 0); rb_define_method(rb_cNumeric, "denominator", numeric_denominator, 0); - rb_define_method(rb_cNumeric, "quo", numeric_quo, 1); + rb_define_method(rb_cNumeric, "quo", rb_numeric_quo, 1); rb_define_method(rb_cInteger, "numerator", integer_numerator, 0); rb_define_method(rb_cInteger, "denominator", integer_denominator, 0); Index: time.c =================================================================== --- time.c (revision 58920) +++ time.c (revision 58921) @@ -144,7 +144,7 @@ quov(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/time.c#L144 return LONG2FIX(c); } } - ret = rb_funcall(x, id_quo, 1, y); + ret = rb_numeric_quo(x, y); if (RB_TYPE_P(ret, T_RATIONAL) && RRATIONAL(ret)->den == INT2FIX(1)) { ret = RRATIONAL(ret)->num; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/