Skip to content

Instantly share code, notes, and snippets.

@knu
Last active March 16, 2020 13:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knu/5a0b7236f7285d305cde0f2dec74098d to your computer and use it in GitHub Desktop.
Save knu/5a0b7236f7285d305cde0f2dec74098d to your computer and use it in GitHub Desktop.
Computing age in Ruby
# frozen_string_literal: true
require 'benchmark/ips'
require 'date'
Benchmark.ips do |x|
x.config(time: 5, warmup: 2)
funcs = [
->(a, b) {
(a.strftime('%Y%m%d').to_i - b.strftime('%Y%m%d').to_i) / 10000
},
->(a, b) {
(a.year - b.year) + (([a.month, a.day] <=> [b.month, b.day]) < 0 ? -1 : 0)
},
->(a, b) {
(a.year - b.year) + ((mdiff = a.month - b.month) < 0 || (mdiff == 0 && a.day < b.day) ? -1 : 0)
},
->(a, b) {
(((a.year * 100 + a.month) * 100 + a.day) - ((b.year * 100 + b.month) * 100 + b.day)) / 10000
},
]
today = Date.new(2020, 3, 16)
cases = {
Date.new(1990, 2, 10) => 30,
Date.new(1990, 3, 16) => 30,
Date.new(1990, 3, 17) => 29,
Date.new(1990, 4, 10) => 29,
}
funcs.each_with_index { |func, i|
cases.each { |date, expected_age|
age = func[today, date]
age == expected_age or abort "func[#{i}]: wrong result #{ages} instead of #{expected_age} when #{date} is given"
}
}
funcs.each_with_index { |func, i|
x.report("func[#{i}]") {
cases.each_key { |date|
func[today, date]
}
}
}
x.compare!
end
Warming up --------------------------------------
func[0] 32.547k i/100ms
func[1] 48.332k i/100ms
func[2] 107.318k i/100ms
func[3] 94.036k i/100ms
Calculating -------------------------------------
func[0] 339.420k (± 5.9%) i/s - 1.692M in 5.005850s
func[1] 567.619k (± 3.0%) i/s - 2.852M in 5.028401s
func[2] 1.325M (± 3.7%) i/s - 6.654M in 5.029764s
func[3] 1.147M (± 3.2%) i/s - 5.736M in 5.007488s
Comparison:
func[2]: 1324806.2 i/s
func[3]: 1146738.6 i/s - 1.16x slower
func[1]: 567619.0 i/s - 2.33x slower
func[0]: 339419.8 i/s - 3.90x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment