[ruby-core:124631] [Ruby Bug#21851] Performance difference between / operator and fdiv
Issue #21851 has been reported by mbrown1intel (Michael Brown). ---------------------------------------- Bug #21851: Performance difference between / operator and fdiv https://bugs.ruby-lang.org/issues/21851 * Author: mbrown1intel (Michael Brown) * Status: Open * ruby -v: ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x64-mingw-ucrt] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Benchmarking fdiv against the / operator, it seems like fdiv is significantly slower. As far as I'm aware there's no functional difference between these two methods. I first ran this on 2.6, and then checked against 4.0 to make sure it hadn't been fixed in the meantime, and saw the same results. ``` ruby require 'benchmark' n = 500_000_000 c = nil Benchmark.bm do |benchmark| benchmark.report("to_f ") do n.times do |i| c = n / i.to_f end end benchmark.report("fdiv ") do n.times do |i| c = n.fdiv(i) end end end ``` ``` user system total real to_f 37.672000 0.110000 37.782000 ( 38.714876) fdiv 113.016000 0.265000 113.281000 (116.428442) ``` -- https://bugs.ruby-lang.org/
Issue #21851 has been updated by byroot (Jean Boussier). Profile with `/ .to_f`: https://share.firefox.dev/4rbNEEW Profile with `fdiv`: https://share.firefox.dev/4qeMwzK In short, `fdiv` end up in the `gcd` path, which is indeed much slower. We could certainly recognize this case and add a fastpath, not sure I'd consider this a bug though. ---------------------------------------- Bug #21851: Performance difference between / operator and fdiv https://bugs.ruby-lang.org/issues/21851#change-116220 * Author: mbrown1intel (Michael Brown) * Status: Open * ruby -v: ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x64-mingw-ucrt] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Benchmarking fdiv against the / operator, it seems like fdiv is significantly slower. As far as I'm aware there's no functional difference between these two methods. I first ran this on 2.6, and then checked against 4.0 to make sure it hadn't been fixed in the meantime, and saw the same results. ``` ruby require 'benchmark' n = 500_000_000 c = nil Benchmark.bm do |benchmark| benchmark.report("to_f ") do n.times do |i| c = n / i.to_f end end benchmark.report("fdiv ") do n.times do |i| c = n.fdiv(i) end end end ``` ``` user system total real to_f 37.672000 0.110000 37.782000 ( 38.714876) fdiv 113.016000 0.265000 113.281000 (116.428442) ``` -- https://bugs.ruby-lang.org/
Issue #21851 has been updated by mame (Yusuke Endoh). It seems `Integer#fdiv` uses gcd for accuracy in #13078. I'm not entirely sure why they only aimed to make `fdiv` accurate but not `/`. Anyway, is this difference causing any real-world issues? If so, it's worth considering a fix. If just for performance consistency, doing nothing might be good enough. ---------------------------------------- Bug #21851: Performance difference between / operator and fdiv https://bugs.ruby-lang.org/issues/21851#change-116223 * Author: mbrown1intel (Michael Brown) * Status: Open * ruby -v: ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x64-mingw-ucrt] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Benchmarking fdiv against the / operator, it seems like fdiv is significantly slower. As far as I'm aware there's no functional difference between these two methods. I first ran this on 2.6, and then checked against 4.0 to make sure it hadn't been fixed in the meantime, and saw the same results. ``` ruby require 'benchmark' n = 500_000_000 c = nil Benchmark.bm do |benchmark| benchmark.report("to_f ") do n.times do |i| c = n / i.to_f end end benchmark.report("fdiv ") do n.times do |i| c = n.fdiv(i) end end end ``` ``` user system total real to_f 37.672000 0.110000 37.782000 ( 38.714876) fdiv 113.016000 0.265000 113.281000 (116.428442) ``` -- https://bugs.ruby-lang.org/
Issue #21851 has been updated by mbrown1intel (Michael Brown). No, this isn't causing me any issues, I just would prefer fdiv for my own codebase for readability. But with that large of a performance difference I think I would stick with "/". ---------------------------------------- Bug #21851: Performance difference between / operator and fdiv https://bugs.ruby-lang.org/issues/21851#change-116231 * Author: mbrown1intel (Michael Brown) * Status: Open * ruby -v: ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x64-mingw-ucrt] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Benchmarking fdiv against the / operator, it seems like fdiv is significantly slower. As far as I'm aware there's no functional difference between these two methods. I first ran this on 2.6, and then checked against 4.0 to make sure it hadn't been fixed in the meantime, and saw the same results. ``` ruby require 'benchmark' n = 500_000_000 c = nil Benchmark.bm do |benchmark| benchmark.report("to_f ") do n.times do |i| c = n / i.to_f end end benchmark.report("fdiv ") do n.times do |i| c = n.fdiv(i) end end end ``` ``` user system total real to_f 37.672000 0.110000 37.782000 ( 38.714876) fdiv 113.016000 0.265000 113.281000 (116.428442) ``` -- https://bugs.ruby-lang.org/
Issue #21851 has been updated by nobu (Nobuyoshi Nakada). [GH-16144](https://github.com/ruby/ruby/pull/16144) ---------------------------------------- Bug #21851: Performance difference between / operator and fdiv https://bugs.ruby-lang.org/issues/21851#change-116378 * Author: mbrown1intel (Michael Brown) * Status: Open * ruby -v: ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x64-mingw-ucrt] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Benchmarking fdiv against the / operator, it seems like fdiv is significantly slower. As far as I'm aware there's no functional difference between these two methods. I first ran this on 2.6, and then checked against 4.0 to make sure it hadn't been fixed in the meantime, and saw the same results. ``` ruby require 'benchmark' n = 500_000_000 c = nil Benchmark.bm do |benchmark| benchmark.report("to_f ") do n.times do |i| c = n / i.to_f end end benchmark.report("fdiv ") do n.times do |i| c = n.fdiv(i) end end end ``` ``` user system total real to_f 37.672000 0.110000 37.782000 ( 38.714876) fdiv 113.016000 0.265000 113.281000 (116.428442) ``` -- https://bugs.ruby-lang.org/
participants (4)
-
byroot (Jean Boussier) -
mame (Yusuke Endoh) -
mbrown1intel (Michael Brown) -
nobu (Nobuyoshi Nakada)