Perfomance improvement

Hi.

What do you think about these changes:

#current_behaviour
def ordinal(number  )
abs_number = number.to_i.abs
if (11..13).include?(abs_number % 100    )
"th"
  else
    case abs_number % 10
      when 1; "st"
      when 2; "nd"
      when 3; "rd"
      else    "th"
    end
  end
end

#new behaviour
def ordinal2(number  )
tmp = number.to_i.abs % 100

  if 11 <= tmp && tmp <= 13
    "th"  .freeze
else
    case tmp % 10
      when 1; "st"      .freeze
when 2; "nd"      .freeze
when 3; "rd"      .freeze
else    "th"    .freeze
end
  end
end

Benchmark.ips do |x  |
x.report('before') { ordinal(1523  ) }
x.report('after') { ordinal2(1523  ) }
x.compare!
end
              Calculating -------------------------------------
before 111.577k i/100ms
after 143.646k i/100ms

:+1: PR welcome.

It can goes further if using a hash instead of a case statement:

#other new behavior

ORDS = { 1 => 'st', 2 => 'nd', 3 => 'rd' } ORDS.default = 'th' ORDS.freeze def ordinal3(number) tmp = number.to_i.abs % 100 if 11 <= tmp && tmp <= 13 ‘th’.freeze else ORDS[tmp % 10].freeze end end

``

require ‘benchmark/ips’ #current_behaviour def ordinal(number) abs_number = number.to_i.abs

if (11…13).include?(abs_number % 100) “th” else case abs_number % 10 when 1; “st” when 2; “nd” when 3; “rd” else “th” end end end

#new behaviour def ordinal2(number) tmp = number.to_i.abs % 100

if 11 <= tmp && tmp <= 13 “th”.freeze else case tmp % 10 when 1; “st”.freeze when 2; “nd”.freeze when 3; “rd”.freeze else “th”.freeze end end end

ORDS = { 1 => ‘st’, 2 => ‘nd’, 3 => ‘rd’ } ORDS.default = ‘th’ ORDS.freeze

#other new behavior def ordinal3(number) tmp = number.to_i.abs % 100 if 11 <= tmp && tmp <= 13 ‘th’.freeze else ORDS[tmp % 10].freeze end end

Benchmark.ips do |x| x.report(‘before’) { ordinal(1523) } x.report(‘after 1’) { ordinal2(1523) } x.report(‘after 2’) { ordinal3(1523) }

x.compare! end

``