Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Junilu Lacar
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Rob Spoor
  • Bear Bibeault
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Piet Souris
  • Carey Brown
  • Stephan van Hulst
Bartenders:
  • Frits Walraven
  • fred rosenberger
  • salvin francis

Switch Or If else - efficency discussion

 
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Winston Gutkowski wrote:

Ulf Lindqvist wrote:You're wrong because the "probability of choises" criterion I mention in my previous reply is implementation independent.


I'm not "wrong" unless you can:
(a) Point me to the relevant paragraph in the JLS or JVM spec that specifies HOW a switch statement is executed.
(b) Convince me that the choice of if over switch - even when probabilities are not uniform - is so overwhelming that it overrides the many other concerns already mentioned.

Your statement also only makes sense if you take into account the length of time it takes to evaluate each test expression and order by probability products - and do you really want to do that? I suspect also that for some varieties of test and a good optimizing compiler, switch might only ever need to evaluate the test condition once, whereas an if stack is far more likely to need to evaluate each case in turn.



My advice is in the best practice category. It's not to be found in the JLS. Actually very little advice of this kind is. The grammar and sematics of a language is one thing, it's effective usage based on practice and experience and knowledge of computer science in general is another. For example considering the JLS alone you would have no idea the OO paradigm is specifically supported by Java because it's not even mentioned once.

I stand by my advice: Prefer a switch but consider replacing it with an if-else chain when the selection probabilities are known and (strongly) non-uniform, and then arrange the chain so the more likely a selection is to be true the earlier it's evaluated.

If the statements involved work like they're defined to work according to the JLS then this opens up for a lower amortized time cost which means higher efficiency. It's not an early optimization, it's about selecting the best algorithm for the job. This is what good programmers do all the time as they lay down the code.

Finally my advice would be different if the JLS guaranteed the switch statement made selections in constant time, but it doesn't. If it did my advice would be: Prefer a switch. Period.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Ulf Lindqvist wrote:My advice is in the best practice category. It's not to be found in the JLS. Actually very little advice of this kind is.


And with good reason.

The grammar and sematics of a language is one thing, it's effective usage based on practice and experience and knowledge of computer science in general is another.


Quite right. And virtually all computer scientists agree that clarity of code is BY FAR the most important consideration when looking at anything of this nature. And with very few exceptions, they all agree with Donald Knuth.

For example considering the JLS alone you would have no idea the OO paradigm is specifically supported by Java because it's not even mentioned once.


Oh, then what is:
"The Java programming language is a general-purpose concurrent class-based object-oriented programming language"
doing in the Preface to the first Edition, written by Gosling himself (2nd paragraph).

Finally my advice would be different if the JLS guaranteed the switch statement made selections in constant time, but it doesn't.


And how, pray tell, would it do that, particularly now that Strings can be used?

I stand by my advice: Prefer a switch but consider replacing it with an if-else chain when the selection probabilities are known and (strongly) non-uniform, and then arrange the chain so the more likely a selection is to be true the earlier it's evaluated.


Right, well since your "advice" seems to be based solely on your opinion rather than any verifiable expert corroboration, I think I'll take it with a pinch of salt, thanks.

Winston

PS: For anyone who wishes to contribute; this is a continuation of this thread - split as we were getting off-topic.
 
Ulf Lindqvist
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Jayesh A Lalwani wrote:
Actually, no you are wrong. I ran this unit test.



Sure you did but what are you measuring really? It seems the test code is spending most of the time doing other things than comparing the alternatives. And do you really print during execution? If you do it's bad and if you don't the code does nothing and is subject to optimization and may even be removed so that's bad too. In short you don't know what you're measuring here.

But, putting the traps of performance testing aside, please consider this quote of yours,

"This is mainly because the testId runs a comparison 3 times, whereas switch probably (my emphasis) does it one operation. However, like Winston said, this is highly dependent on the JVM, and actually the OS and even the CPU."

That's right. The JLS presents the switch statement from a grammatical and semantic point of view only. Other properties are subject to guessing. And this is why my advice makes sense. Utilizing application specific knowledge to remove implementation dependencies, that's a fine cigarr.


 
lowercase baba
Posts: 12992
66
Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Ulf Lindqvist wrote:My advice is in the best practice category. It's not to be found in the JLS.


Where is it to be found? If it is a "best practice", then what source do you have? I have seen tons of books/articles/whatevers that say writing clean, easy to read code should be the number 1 priority. Now you are coming along and are saying "No, that's wrong...something else is considered a best practice". If it is, I would expect it to be written down somewhere.

I am not saying you are wrong.

I am just saying that since you are claiming something that most folks here have never heard (and in fact, we've heard quite the opposite), you need to provide some evidence that this is a "best practice".
 
Rancher
Posts: 2759
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Ulf Lindqvist wrote:

Jayesh A Lalwani wrote:
Actually, no you are wrong. I ran this unit test.



Sure you did but what are you measuring really? It seems the test code is spending most of the time doing other things than comparing the alternatives. And do you really print during execution? If you do it's bad and if you don't the code does nothing and is subject to optimization and may even be removed so that's bad too. In short you don't know what you're measuring here.



No, I know what I'm testing here, because the only differrence between the test methods is the if-else chain vs switch statement. ANy overheads in using Random and SYstem.outs will be the same in both test methods, and by running a million iterations, any performance variances in those methods should cancel out.

Are you saying that your claim is essentially unprovable because there is no way to test it?. The highly technical term for that is bullshit. You made a claim that using an if-else chain is always more efficient than using a switch when you take the probability of choices into account. I constructed a test that shows your claim to be wrong. Either construct a test that shows your claim to be true, or modify your claim. That's the scientific method.
 
Ulf Lindqvist
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Jayesh A Lalwani wrote:
No, I know what I'm testing here, because the only differrence between the test methods is the if-else chain vs switch statement.



Well that's not enought.

What you're comparing should constitute the major part of the test methods. Otherwise any difference will be lost in the bulk of the test methods. What you want to measure must stick out, right.

That's one problem with your test, among many.
 
Ulf Lindqvist
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Winston Gutkowski wrote:
"The Java programming language is a general-purpose concurrent class-based object-oriented programming language"
doing in the Preface to the first Edition, written by Gosling himself (2nd paragraph).



Okay, in the preface to the first edition of the JLS you managed to find a reference to OO. But then it's gone because the JLS shouldn't care as you should know.

The JLS supports my advice. It does that by not giving any performance guarantees on the switch statement. So prefer a switch unless you know the selection probabilities, then prefer an if-else chain.

My advice is fully supported by the JLS. Your opposition is based on your personal view only. You have no support in the JLS whatsoever.
 
Master Rancher
Posts: 3937
51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Ulf Lindqvist wrote:

Winston Gutkowski wrote:
"The Java programming language is a general-purpose concurrent class-based object-oriented programming language"
doing in the Preface to the first Edition, written by Gosling himself (2nd paragraph).



Okay, in the preface to the first edition of the JLS you managed to find a reference to OO. But then it's gone because the JLS shouldn't care as you should know.


Ummm, it's also in line 1, chapter 1, the introduction. And mentioned again later in the chapter. For every single edition of the JLS ever published, to date. Also a few other places, easily Googled.
 
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator
Wow, a "language lawyer" have not seen one of those in years. They used to be all over the place in Java newsgroups, not missed.
 
Mike Simmons
Master Rancher
Posts: 3937
51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator
Not sure how that's constructive, Bill. Also, there seem to be three of us involved on this last point you're replying to - are you targeting one of us in particular?
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Ulf Lindqvist wrote:Okay, in the preface to the first edition of the JLS you managed to find a reference to OO. But then it's gone because the JLS shouldn't care as you should know.


What? The specification for a language shouldn't care that it's Object-Oriented? This is getting funnier and funnier.

The JLS supports my advice.


Where?

It does that by not giving any performance guarantees on the switch statement...My advice is fully supported by the JLS.


Ah, so that would be the old "support by saying absolutely nothing" paradigm then, would it?

Your opposition is based on your personal view only. You have no support in the JLS whatsoever.


My "opposition" was actually posted long before yours, and appears to be in line with most of the other people here. You, on the other hand, appear to be enitrely assured of your own correctness, despite the fact that you have so far signally failed to:
(a) Provide one shred of supporting text from either the JLS or the JVM spec.
(b) Produce a single corroborating statement from any recognised expert to back your claim.
(c) Convince anyone else.

To be honest, I'm done. Feel free to argue with yourself.

Winston
 
Mike Simmons
Master Rancher
Posts: 3937
51
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator
So I gather this topic was extracted from this previous topic. The resulting thread here is missing quite a bit of context, particularly the performance test code that people are going on about. Now that I've found the code in question, I have to say that I agree, it seems a very poor practice to put System.out statements in the middle of the very thing you're trying to test. Those are so much slower than anything else in the code, the signal gets lost in all the noise. Here's my attempt to improve on that:

I moved I/O and test data setup out of the timed portion, so we can focus more clearly on actual differences between switch and if/else. I also added another test, and modified the switch to test the difference between the tableswitch and lookupswitch commands. Basically, if the values in the switch are all closely clustered, it compiles to a tableswitch, while more sparse values compile to a lookupswitch. See Compiling switches for more information. You can run javap -c on the resulting class file to verify whether these tests do in fact get compiled to tableswitch and lookupswitch, respectively - but they do for me.

In the test shown, I got the tableswitch to be about 8% faster than the if statements, and 1% faster than the lookupswitch. Of course, this can vary depending on a variety of factors, and yes, there are no guarantees, yadda yadda. But common sense suggests that tableswitch will be O(1), while lookupswitch will be O(log(N)) where N is the number of choices. And if statements are O(N), unless one orders them into a nice tree of inequalities, which could get O(N). As noted above, if the probabilities are nonuniform, there's an opportunity for the if statements to be quicker than the lookupswitch, at least. But it's going to have a hard time ever beating the tableswitch. Maybe only in the case where the first option is much more likely than all the others combined, in which case the if statements effectively reduce to a single if statement evaluation.

So, in my opinion, based purely on the likely best performance:

If your options are compact enough to compile to a tableswitch, use a switch statement.

Otherwise, if the probabilities for the options are very nonuniform, and of known approximate value, you may be able to get the if statements to be faster. But don't bet on it.

In general, I'd just use a switch statement and not worry about it, unless and until it gets identified as a performance problem. Which I consider extremely unlikely.

And of course, there are many conditional expressions which cannot be rendered as switch statements, only ifs. For those, use ifs. Naturally.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Report post to moderator

Mike Simmons wrote:So I gather this topic was extracted from this previous topic. The resulting thread here is missing quite a bit of context, particularly the performance test code that people are going on about.


Actually, it's here (I think possibly you typed the URL in wrong?), and I did provide a link in the first post-split post. But thanks for your test prog and analysis; I always like stuff like that.

I still stand by my original statement though: You can't know which is faster, because neither the JLS nor the JVM spec specify how switch is encoded, so the only real test is to do exactly what you've done. And my basic point (to the OP of the original thread, not to Ulf, who seems to have hijacked the topic) was that readability is far more important than any nanosecond-shaving you might gain by using one or the other.

Personally, I like switch because I find it more visual, so I'll generally use it when I can; but the fact is, both constructs smell of dispatch code, so I'll actually check to see if I can avoid using either of them if I can do so first.

Winston
 
I found a beautiful pie. And a tiny ad:
Thread Boost feature
https://coderanch.com/t/674455/Thread-Boost-feature
    Bookmark Topic Watch Topic
  • New Topic