From: "mame (Yusuke Endoh) via ruby-core" Date: 2025-10-28T09:29:56+00:00 Subject: [ruby-core:123563] [Ruby Feature#21650] Performance regression: Rational#floor(ndigits) extremely slow for huge ndigits in Ruby 3.4 (ok in 3.2) Issue #21650 has been updated by mame (Yusuke Endoh). Tracker changed from Bug to Feature Status changed from Open to Feedback ruby -v deleted (ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [arm64-darwin24]) Backport deleted (3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN) Thank you for your reply. I found a clearer case: ```ruby p Rational(1, 3).floor(2**1) #=> (33/100) p Rational(1, 3).floor(2**2) #=> (3333/10000) p Rational(1, 3).floor(2**3) #=> (33333333/100000000) p Rational(1, 3).floor(2**4) #=> (3333333333333333/10000000000000000) # in Ruby 3.3 p Rational(1, 3).floor(2**30) #=> warning: in a**b, b may be too big #=> (1/3) ``` Also, I think you can immediately see that this operation generally cannot be O(1). An improvement might be possible by creating a specialized "fast path" for cases where the denominator's prime factors are only 2 and 5. I will move this ticket to the Feature tracker. However, if there is no use case for this, we may need to consider if the added complexity is worth it. ---------------------------------------- Feature #21650: Performance regression: Rational#floor(ndigits) extremely slow for huge ndigits in Ruby 3.4 (ok in 3.2) https://bugs.ruby-lang.org/issues/21650#change-114943 * Author: koilanetroc (Oleg Tolmashov) * Status: Feedback ---------------------------------------- ## Summary `Rational#floor(ndigits)` with a very large positive ndigits takes tens of seconds in Ruby 3.4, while it returns essentially instantly in Ruby 3.2. Reproducible on macOS and Linux. Looks like a missing fast���path for rationals whose decimal expansion terminates. ## Steps to reproduce ```ruby require "benchmark" puts RUBY_DESCRIPTION t = Benchmark.realtime { (2 ** -3).floor(2 ** 31) } puts "elapsed: #{t.round(3)}s" ``` Also reproduces with the explicit rational form: ```ruby Benchmark.realtime { Rational(1, 8).floor(2 ** 31) } ``` ### Results on my machine Ruby 3.2.8: ``` ruby 3.2.8 (2025-03-26 revision 13f495dc2c) [arm64-darwin24] slow_math.rb:4: warning: in a**b, b may be too big elapsed: 0.0s ``` Ruby 3.4.7: ``` ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [arm64-darwin24] elapsed: 39.214s ``` ## Actual behavior On Ruby 3.4.x this call takes ~tens of seconds (e.g., ~40s on my machine), consuming CPU. Same on macOS and Linux. ## Expected behavior The method should return quickly ������������������ ���� -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/