Skip to content

Correcting Performance/BigDecimalWithNumericArgument offences leads to slower code #454

@owst

Description

@owst

Performance/BigDecimalWithNumericArgument suggests that BigDecimal(2000) is more performant as BigDecimal("2000") but that is not the case for recent versions of Ruby/BigDecimal:

require 'benchmark/ips'
require 'bigdecimal'

Benchmark.ips do |x|
  x.report('integer string new')  { BigDecimal("2000") }
  x.report('integer new')         { BigDecimal(2000) }
  x.compare!
end

Gives for me (using Ruby 3.3.3 and BigDecimal 3.1.8):

ruby 3.3.3 (2024-06-12 revision f1c7b6f435) [x86_64-darwin22]
Warming up --------------------------------------
  integer string new   228.898k i/100ms
         integer new   337.726k i/100ms
Calculating -------------------------------------
  integer string new      2.520M (± 5.9%) i/s -     12.589M in   5.015809s
         integer new      4.443M (±10.5%) i/s -     21.952M in   5.006675s

Comparison:
         integer new:  4442710.0 i/s
  integer string new:  2519800.0 i/s - 1.76x  slower

Having dug a little bit through various Ruby/BigDecimal versions, I think the improvement was introduced in BigDecimal 3.1.0 (which was first included in Ruby 3.1.0), I suspect this PR led to the performance improvement ruby/bigdecimal#178

Expected behavior

There should be no offence for the faster code BigDecimal(2000)

Actual behavior

There was an offence.

Steps to reproduce the problem

Run rubocop-performance against a file containing BigDecimal(2000)

RuboCop version

1.61.0 (using Parser 3.3.3.0, rubocop-ast 1.31.3, running on ruby 3.3.3) [x86_64-darwin22]
  - rubocop-performance 1.21.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions