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
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
``