• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Switch or If Statements

 
Stu Higgs
Ranch Hand
Posts: 74
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Which is more efficient, a Switch or If statement? I know it may depend on the details of the implementation, but for my purposes this is a very simple matter of not wanting to clutter my code with nested if statements for two simple conditions: for example, in a for loop i = 0 or i != 0 then do something. Is it appropriate/less or more efficient to use a Switch in the for loop? See code Examples Below:

for(int i = 0; i < loops; i++){

try{

switch(i){
case 0:
if(stringLength < chunkSize){
sTmp = new String(s.substring(0, stringLength));
list.add(sTmp);
}else{
sTmp = new String(s.substring(0, chunkSize));
list.add(sTmp);
}
break;
//}else{
default:
if(nStringPosition2 > stringLength){

sTmp = new String(s.substring(nStringPosition1, stringLength));
list.add(sTmp);

}else{

sTmp = new String(s.substring(nStringPosition1, nStringPosition2));
nStringPosition1 = nStringPosition1+chunkSize;
nStringPosition2 = nStringPosition2+chunkSize;
list.add(sTmp);

}
break;
}


}catch(StringIndexOutOfBoundsException e){

System.out.println("StringIndexOutOfBoundsException "+e);

break;

}


}

Thanks for your reply!
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 34669
367
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stu,
They compile to essentially the same thing, so it isn't a performance consideration.

Your instinct is correct in wanting to make the code clearer. Personally, I find the switch to be less clear since it only has one case.

Two things I can think of to make things clearer:
1) Move the contents of the outer if to a separate method. This will make the flow more readable.
2) Do you want to continue the loop if an exception is thrown? If not, the try/catch can be moved futher out.
 
Stu Higgs
Ranch Hand
Posts: 74
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your reply Jeanne. I do think it would be more appropriate to use the switch if there were more cases, but for some reason I just don't like nesting if statements very much so I will experiment with your suggestions. Thanks very much!

Regards,
Stu
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24211
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stu --

I can't help but notice that, although you're asking about an extreme micro-optimization (the difference between the performance of two similar JVM opcodes, essentially,) at the same time in this example code you're doing something that takes literally 100 times more time, and is 100% unnecessary right here:

sTmp = new String(s.substring(0, stringLength));

It is never necessary -- absolutely, positively never necessary -- to copy a String in Java. Strings are immutable, meaning once created, their values never change; and unlike C, there's no such thing as a stack-based object that must be copied to be stored. So the right thing to do it

sTmp = s.substring(0, stringLength);

and the performance savings is so vast that any consideration of switch vs if is entirely moot!
 
Stu Higgs
Ranch Hand
Posts: 74
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ernest,

Wow! I can not believe I did that without even realizing the consequences. Thanks for your reply.

Stu
 
Ricky Clarkson
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The implementation of substring is such that if you have a String with 10 million characters, and you use substring to get at the first 10, then the substring contains a reference to the char array stored in the main String.

Hence the 10 million char String will not be garbage collected until the 10 char String is unreferenced.

Thus, there is at least (and maybe at most) one case where new String(String) is desirable.

I correct you only because you used the word 'never' - Stu shouldn't worry about this case. Never use new String(String) unless you know why you're doing it.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As it happens, this behavior has been changed as of JDK 5 - substring() now returns a completely new String with its own backing array. Unless the "substring" is of the entire length of the String, in which case it simply returns the original String. But yes, the situation Ricky describes was a perfectly valid reason to use new String(String), at least for any code that may run on JDK 1.4 or earlier. And the behavior is undocumented anyway, so it's possible this may return in the future. Other possible reasons to use new String(String) are for testing or educational purrposes (teaching the difference between == and .equals()). But I agree with the general rule given - don't do it unless you know why you're doing it. Most times I've seen it, it's a complete waste of time.
 
Ricky Clarkson
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I based what I said on Java 1.5, from looking at the source:

String.substring:



That constructor is a package private one that shares the char[] (value) rather than copying it, 'for speed'.

So I'd like to know where you got your info about it being fixed in Java 5.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah, you're right. I knew that backing-array sharing between StringBuffer and String was removed in JDK 5; I was thinking they'd removed all such sharing. My mistake; thanks for the correction.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic