> On Jan 11, 2017, at 03:27, Robert Klemme <shortcutter@googlemail.com> > wrote:
>
> And the generic answer for arbitrary conditions is: use a lambda,
> because my suggestion to make lambda support #=== as an alias for
> #call and # was implemented a long time ago:
As the great Alan Perlis didn't quite say:
> [Ruby] programmers know the value of everything and the cost of nothing.
Generic answers are great for generic questions, but using a proc in this
case (no pun intended) comes with a very large cost. I really liked James'
suggestion, to flip the logic around, but I knew that the range was
What I'm truly surprised by is James' solution being as slow as it was. I
figured it had to beat out proc activation. I'm also a bit surprised at the
cost of my valueless case (ryan2).
---- benchmark and results follow
require 'benchmark/ips'
LARGER_THAN_5 = lambda { |m| m > 5}
def robert n
case n
when 0 then 0
when 1 then 1
when 2 then 2
when 3, LARGER_THAN_5 then 3
else 99
end
end
def robert2 n
case n
when 0,1,2,3 then n
when LARGER_THAN_5 then 3
else 99
end
end
def mike n
case n
when 0 then 0
when 1 then 1
when 2 then 2
when -> (x) { x == 3 || x > 5 } then 3
else 99
end
end
def james n
case n
when 0 then 0
when 1 then 1
when 2 then 2
when 4..5 then 99 # using a range here to cover your original 'else'
clause
else 3 # this is now 'when 3, a > 5'
end
end
def ryan n
case n
when 0 then 0
when 1 then 1
when 2 then 2
when 4, 5 then 99 # because range will bite you
else 3
end
end
def ryan2 n
case
when n==0 then 0
when n==1 then 1
when n==2 then 2
when n==3 || n>5 then 3 # just to see the impact of a valueless case
else 99
end
end
10.times do |n|
v0, v1, v2, v3, v4, v5 =
robert(n), robert2(n), mike(n), james(n), ryan(n), ryan2(n)
abort "bad" if [v0, v1, v2, v3, v4, v5].uniq.size != 1
end
Benchmark.ips do |x|
x.report("robert") do |t| t.times do 10.times do |n| robert n end end
end
x.report("robert2") do |t| t.times do 10.times do |n| robert2 n end end
end
x.report("james") do |t| t.times do 10.times do |n| james n end end
end
x.report("mike") do |t| t.times do 10.times do |n| mike n end end
end
x.report("ryan") do |t| t.times do 10.times do |n| ryan n end end
end
x.report("ryan2") do |t| t.times do 10.times do |n| ryan2 n end end
end
x.compare!
end
# Calculating -------------------------------------
# robert 278.388k (+/- 2.8%) i/s - 1.408M in
5.059990s
# robert2 283.350k (+/- 2.4%) i/s - 1.425M in
5.031756s
# james 264.979k (+/- 3.3%) i/s - 1.344M in
5.079088s
# mike 139.618k (+/- 3.8%) i/s - 701.028k in
5.029633s
# ryan 849.322k (+/- 3.0%) i/s - 4.300M in
5.067430s
# ryan2 640.050k (+/- 2.5%) i/s - 3.209M in
5.016532s
#
# Comparison:
# ryan: 849322.2 i/s
# ryan2: 640050.3 i/s - 1.33x slower
# robert2: 283349.9 i/s - 3.00x slower
# robert: 278387.7 i/s - 3.05x slower
# james: 264979.4 i/s - 3.21x slower
# mike: 139618.4 i/s - 6.08x slower
Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>