Performance diffrence between ifs and case


#1

What kind of diffrences are there, effectivly, between case and a series
of if statements, like in this:

if i=“hi”
puts “hi”
elsif i=“bye”
puts “bye”
else
puts i
end

and

case i
when hi
puts “hi”
when bye
puts “bye”
else
puts i
end


#2

forgottenwizard wrote:

What kind of diffrences are there, effectivly, between case and a series
of if statements, like in this:

Google for “premature optimization is the root of all evil”.

Ruby is not the most performant language on the block, and both those
statements will resolve to a chain of conditionals. You need to devote
your
time to making clear readable code that’s easy to upgrade. When the time
comes to speed it up, if you have unit tests, you can change it easily,
while profiling to see what’s actually slow. Trying to guess what will
be
slow will only make you waste time writing complex code.

The most important resource to optimize is programmer time.


#3

On 10:29 Sun 29 Jul , Phlip wrote:

comes to speed it up, if you have unit tests, you can change it easily,

Okay, to sum up what you said, not a damn thing? Thats all the answer I
needed, not an explination why I shouldn’t bother to care how to do
things properly, or why I would not want to try and learn a little more
on the internals of a language.


#4

Or, just write code using case, then code using if’s
then test it.
Ruby has a testing facility in the standard library!
That’s the quickest way to find out.


#5

forgottenwizard wrote:

Okay, to sum up what you said, not a damn thing? Thats all the answer I
needed, not an explination why I shouldn’t bother to care how to do
things properly, or why I would not want to try and learn a little more
on the internals of a language.

Ah, but I said it much more diplomatically than Tony Hoare and/or Don
Knuth
did!

Learn the internals of Ruby; they rock. However, optimization is a
sore-spot
around here, because the language is slower than molasses in January (in
the Norther Hemisphere).


#6

On 10:53 Sun 29 Jul , John J. wrote:

Or, just write code using case, then code using if’s
then test it.
Ruby has a testing facility in the standard library!
That’s the quickest way to find out.

Is there any idea on which way the aforementioned systems will evolve,
or is that kind of a toss-up.

What I’m doing right now, it doesn’t make much of a diff either way, so
I’ll use case sinces its less typing…


#7

forgottenwizard wrote:

Is there any idea on which way the aforementioned systems will evolve,
or is that kind of a toss-up.

There’s at least one attempt out there to write a compiler for Ruby.
That
requires a re-write, and while of course its goal is more performance,
the
exact resulting mix will indeed be a toss-up.

What I’m doing right now, it doesn’t make much of a diff either way, so
I’ll use case sinces its less typing…

So … ‘case’ is more “DRY”?


#8

On 7/28/07, forgottenwizard removed_email_address@domain.invalid wrote:

What kind of diffrences are there, effectivly, between case and a series
of if statements, like in this:

Because of the way case works, it will depend on what you are trying to
do.
Use the benchmark standard library for your use case to find out which
is more efficient.


#9

On 11:41 Sun 29 Jul , Phlip wrote:

I’ll use case sinces its less typing…

So … ‘case’ is more “DRY”?

It seems to me, that since I can’t tell a real diffrence (I’ll look into
the benchmarking bits later), I might as well use what seems the easiest
to expand as things go along.

Less to type in

case i
when arg,a

when arb,b

instead of
if i=“arg” or i=“a”

:slight_smile:


#10

Phlip wrote:

forgottenwizard wrote:

What kind of diffrences are there, effectivly, between case and a series
of if statements, like in this:

Google for “premature optimization is the root of all evil”.

Classify as “nostrum-emitting moron.”


#11

On Sun, 29 Jul 2007, Sean S. wrote:

Phlip wrote:

forgottenwizard wrote:

What kind of diffrences are there, effectivly, between case and a series
of if statements, like in this:

Google for “premature optimization is the root of all evil”.

Classify as “nostrum-emitting moron.”

a) Phlip emits very valid and important nostrums.
b) Definitely not a moron, you’ll miss some Good Stuff if you make that
mistake.
c) Once anyone actually benchmarks the difference and hence contributes
real data to the
discussion…

Write it up here…
http://rubygarden.org/ruby/page/show/RubyOptimization
…the wiki page where I keep breadcrumbs of info for when desperation
requires me to shovel perfectly correct nostrums to one side and put in
a twist of
speed.

Speaking of which… Rubygarden seems to be slow…

Gah! Spammers have totally vandalized that page. Twice. Hmm. That’s
probably
why it’s so slow, probably a major spam attack…

I hate spammers. Really the complete scum of the earth. The Lambda the
Ultimate (excellent programming language design site)
http://lambda-the-ultimate.org crew have also been under attack.

Anyway, Ruby garden has nice review and revert facilities so it’s fixed
now.

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : removed_email_address@domain.invalid
New Zealand


#12

John C. wrote:

Speaking of which… Rubygarden seems to be slow…

Gah! Spammers have totally vandalized that page. Twice. Hmm. That’s
probably
why it’s so slow, probably a major spam attack…

I hate spammers. Really the complete scum of the earth. The Lambda the
Ultimate (excellent programming language design site)
http://lambda-the-ultimate.org crew have also been under attack.

Nobody is willing to do what it will take to eliminate spam (and for
that matter, junk snail mail), namely, tax it. :slight_smile:


#13

If you can come up with a way to tax spammers w/o causing problems for
normal traffic and fully eliminating spam, then by all means do so.
Personally, I’d prefer just find who is responsibe, and beat them to
within an inch of their lives and remove all their computer rights
permanently.


#14

On 7/28/07, forgottenwizard removed_email_address@domain.invalid wrote:

end
end

As you’ve written the code, the first example will probably run
noticeably
faster because it will never perform a comparison. The assignment in the
first if statement will always be true, and so the first branch will
always
be taken.

To answer a related question (but one that you didn’t ask): case/when
uses
the === operator rather than ==, which is typically used in if/when
constructions that (unlike yours) are intended to perform comparisons
rather
than assignments.

And perhaps surprisingly, === is extremely slow when applied to
arguments
that are Symbols. In those cases, I always use if/else.


#15

On 13:47 Mon 30 Jul , Francis C. wrote:

    puts i
    puts i

To answer a related question (but one that you didn’t ask): case/when uses
the === operator rather than ==, which is typically used in if/when
constructions that (unlike yours) are intended to perform comparisons rather
than assignments.

And perhaps surprisingly, === is extremely slow when applied to arguments
that are Symbols. In those cases, I always use if/else.

Actually, I’m going by the contents of ARGV[] with the actual program. I
ran across symbols just awhile ago looking through a few refrences, but
havn’t messed with them any currently.

A more-or-less realistic example would be (just using case here):

case ARGV[9]
when “hi”, “H”
puts “hi”
when "bye, “B”
puts “bye”
else
puts ARGV[9]
end

Don’t know if that makes a diff, but all this is pretty much passed down
through a single starting function as arguments to the function.


#16

On Mon, 30 Jul 2007, forgottenwizard wrote:

Personally, I’d prefer just find who is responsibe, and beat them to
within an inch of their lives and remove all their computer rights
permanently.

And once we’ve got rid of them…

…we can go after those who persist in extending tangential and off
topic threads… ;-D

Sorry, couldn’t resist a good sharp leg pull.

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : removed_email_address@domain.invalid
New Zealand


#17

John C. wrote:

Classify as “nostrum-emitting moron.”

a) Phlip emits very valid and important nostrums.
b) Definitely not a moron, you’ll miss some Good Stuff if you make that
mistake.
c) Once anyone actually benchmarks the difference and hence contributes
real data to the
discussion…
logic_benchmark.rb:

require ‘benchmark’

def nop
end

def if_equiv_method(str)
if “hi” === str
nop
elsif “bye” === str
nop
else
nop
end
end

def if_method(str)
if str == “hi”
nop
elsif str == “bye”
nop
else
nop
end
end

def case_method(str)
case str
when “hi”
nop
when “bye”
nop
else
nop
end
end

strings = %w{hi bye foo}

Benchmark.bmbm(20) do |x|
x.report(“if”){for i in 0…1000000 do
if_method(strings[rand(strings.length)]) end }
x.report(“if_equiv”){for i in 0…1000000 do
if_equiv_method(strings[rand(strings.length)]) end }
x.report(“case”){for i in 0…1000000 do
case_method(strings[rand(strings.length)]) end }
end

Results:

C:\WINDOWS\system32\cmd.exe /c ruby logic_benchmark.rb
Rehearsal -------------------------------------------------------
if 2.578000 0.000000 2.578000 ( 2.610000)
if_equiv 2.797000 0.000000 2.797000 ( 2.953000)
case 2.625000 0.000000 2.625000 ( 2.812000)
---------------------------------------------- total: 8.000000sec

                       user     system      total        real

if 2.578000 0.000000 2.578000 ( 2.625000)
if_equiv 2.781000 0.000000 2.781000 ( 2.828000)
case 2.625000 0.000000 2.625000 ( 2.672000)

It’s pretty marginal, and I did have them come out much closer on some
runs.

Write it up here…
http://rubygarden.org/ruby/page/show/RubyOptimization
…the wiki page where I keep breadcrumbs of info for when desperation
requires me to shovel perfectly correct nostrums to one side and put in
a twist of
speed.

Speaking of which… Rubygarden seems to be slow…
Too slow for me to write this up, as a matter of fact.


#18

On 7/30/07, John C. removed_email_address@domain.invalid wrote:

On Mon, 30 Jul 2007, forgottenwizard wrote:

Personally, I’d prefer just find who is responsibe, and beat them to
within an inch of their lives and remove all their computer rights
permanently.

And once we’ve got rid of them…

…we can go after those who persist in extending tangential and off
topic threads… ;-D
No, your logic is important as of course everybody of us will be the
single sole survivor on earth :frowning:

Sorry, couldn’t resist a good sharp leg pull.
Which was well deserved.
Robert


#19

On 7/30/07, Alex Y. removed_email_address@domain.invalid wrote:

Benchmark.bmbm(20) do |x|
x.report(“if”){for i in 0…1000000 do

Yuck!

1000000.times do … end


#20

Gregory B. wrote:

On 7/30/07, Alex Y. removed_email_address@domain.invalid wrote:

Benchmark.bmbm(20) do |x|
x.report(“if”){for i in 0…1000000 do

Yuck!

1000000.times do … end

Meh.

require ‘benchmark’

def nop
end

Benchmark.bmbm(20) do |x|
x.report(“range”){for i in 0…1000000 do nop end}
x.report(“times”){1000000.times do nop end}
end

Rehearsal -------------------------------------------------------
range 0.578000 0.000000 0.578000 ( 0.594000)
times 0.531000 0.000000 0.531000 ( 0.578000)
---------------------------------------------- total: 1.109000sec

                       user     system      total        real

range 0.578000 0.000000 0.578000 ( 0.594000)
times 0.578000 0.000000 0.578000 ( 0.578000)