Bug #13519
closedImprove performance of some Time methods
Description
This is related to https://bugs.ruby-lang.org/issues/13503
Some Time methods will call internal quov() function and
quov() calls Numeric#quo -> Rational#quo -> ...
This patch will add rb_numeric_quo() as internal C API to call Numeric#quo directly.
And this will use rb_numeric_quo() instead of rb_funcall() for Numeric#quo to internal objects.
Time#- will be faster around 15%.
Before¶
Calculating -------------------------------------
Time#subsec 2.029M (± 8.6%) i/s - 10.078M in 5.003036s
Time#- 4.225M (± 2.1%) i/s - 21.130M in 5.003600s
Time#to_f 5.580M (± 2.1%) i/s - 27.955M in 5.011881s
Time#to_r 1.862M (± 9.8%) i/s - 9.253M in 5.016749s
After¶
Calculating -------------------------------------
Time#subsec 2.196M (±10.7%) i/s - 10.879M in 5.010285s
Time#- 4.991M (± 2.2%) i/s - 24.966M in 5.005041s
Time#to_f 6.809M (±13.5%) i/s - 32.204M in 5.005536s
Time#to_r 1.980M (± 9.6%) i/s - 9.854M in 5.020879s
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
Patch¶
Updated by normalperson (Eric Wong) over 7 years ago
watson1978@gmail.com wrote:
Bug #13519: Improve performance of some Time methods
https://bugs.ruby-lang.org/issues/13519
Some Time methods will call internal quov() function and
quov() calls Numeric#quo -> Rational#quo -> ...This patch will add rb_numeric_quo() as internal C API to call Numeric#quo directly.
And this will use rb_numeric_quo() instead of rb_funcall() for Numeric#quo to internal objects.
I guess this is OK...
I notice this change; along with many similar optimizations in
time.c such as r54218, r54203, ... do not check method
redefinition flags on Integer.
Are we OK with this? (I am)
I guess 2.4 was released with some of these changes;
and nobody complained so far...
Can we disable/disallow redefinition of more methods? :)
Updated by watson1978 (Shizuo Fujita) over 7 years ago
- Status changed from Open to Closed
Applied in changeset trunk|r58921.
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 (± 8.7%) i/s - 10.062M in 5.009762s
Time#- 5.049M (± 4.7%) i/s - 25.186M in 5.002379s
Time#to_f 5.625M (± 4.2%) i/s - 28.066M in 5.000749s
Time#to_r 1.880M (± 9.7%) i/s - 9.361M in 5.027527s
After¶
Time#subsec 2.155M (± 9.7%) i/s - 10.724M in 5.022579s
Time#- 6.362M (± 2.0%) i/s - 31.824M in 5.004625s
Time#to_f 7.287M (± 4.8%) i/s - 36.402M in 5.010983s
Time#to_r 2.020M (± 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