🕌

[Feature #21650] 巨大な数値の場合に Rational#floor(ndigits) が遅くなっているバグ報告

に公開

[Feature #21650] Performance regression: Rational#floor(ndigits) extremely slow for huge ndigits in Ruby 3.4 (ok in 3.2)

  • Ruby 3.2 と比較して Ruby 3.4 で巨大な数値の場合に Rational#floor(ndigits) が遅くなっているというバグ報告
    • 手元で試してみたら Ruby 3.3 -> 3.4 で遅くなっているみたい
require "benchmark"

puts RUBY_DESCRIPTION
t = Benchmark.realtime { (2 ** -3).floor(2 ** 31) }
puts "elapsed: #{t.round(3)}s"
# Ruby 3.2 => elapsed: 0.0s
# Ruby 3.3 => elapsed: 0.0s
# Ruby 3.4 => elapsed: 47.018s
# returns Rational(1, 10**(2**n))
def calc(n)
  d = 10
  n.times { d *= d }
  Rational(1, d)
end

p calc(1) #=> (1/100)
p calc(2) #=> (1/10000)
p calc(3) #=> (1/100000000)

# この2つは期待する挙動
p calc(10).floor(2**10 - 1) == 0 # => true
p calc(20).floor(2**20 - 1) == 0 # => true

# これも true になってほしいが Ruby 3.3 だと false になる
p calc(30).floor(2**30 - 1) == 0
# => false
# => true
GitHubで編集を提案

Discussion