So lately I've been trying to figure out how 'heavy' some statements are.
For example is it a good thing to check for every possible exception with if statements or will that slow down the programm considerably? So I bassically want to know how 'heavy' the folling statements get when used a lot. This is mostly just a question out of curiosity because today's computer are so fast that it probably doesn't matter But it will also help me choose between different ways of doing things though perfomance improvements might only be minimal.
A simple while loop how 'heavy' is the loop itself not the code inside it?
while(true){}
A for loop probably smiliar to the while loop?
for(int i = 0; true; i++){}
A do while loop probably smiliar to the above two too?
do{...}while(true)
An if statement how 'heavy' does this get?
if(true){}
A switch statement
switch(0){
case 0:
}
And is a switch statement less 'heavy' or 'heavier' than else if statements
And the instanceof check how 'heavy' is it?
if(obj instanceof Player){}
An is null check I heard that this one is really 'light' is that true?
if(obj == null){}
And a constructor call
new Object();
And a method call
MyClass.doSomething();
A variable assignment
int i = 10;
I tried searching on the internet but I didn't find a web page that was comparing them all to each other or something smiliar. But if some of you have a good documentation on this I would be more than happy to read it.
The answer to pretty much everything there is "It depends". It depends on the JITC, what's inside those calls, surrounding code, how hot the code is, how good your branch predictor is, etc. But if you're worried about the performance of control flow structures, you're almost certainly looking in the wrong place...
Disclaimer: This analysis goes right out the window if you actually put something in the loops and/or evaluate a "real" condition, because evaluating those would dwarf the cost of the control flow structures themselves. But I'll just take everything literally now, because otherwise I can't give a solid answer.
while(true){}
This would probably be optimized to an unconditional branch by the JITC. So not "heavy" at all.
for(int i = 0; true; i++){}
Again, JITC optimizations could probably turn this into an unconditional branch + increment. "heavier" than while(true), but that's because of the increment more than anything. Probably could be optimized further by the JITC; in this case, it's possible that the increment would be skipped entirely.
do{...} while(true);
Same as while(true). Probably optimized to unconditional branch by JITC.
if(true){}
If this isn't eliminated in bytecode compilation (and it might not be; I think I remember some special rules concerning how control flow is evaluated for if statements), then it'll probably be optimized by the JITC to a no-op and essentially be eliminated from the program.
switch(0){
case 0:
}
Not sure about this case specifically, but I wouldn't be surprised if the JITC optimized this away entirely. Otherwise, a switch could be a jump table or a binary-search-ish instruction, depending on how sparse the cases are.
And is a switch statement less 'heavy' or 'heavier' than else if statements
This depends entirely on 1) whether you can use one instead of the other, and 2) what you are comparing. So can't say anything about this.
if(obj instanceof Player){}
if(obj == null){}
These two particular snippets would probably be removed by the JITC, otherwise I would expect that instanceof and == null would be reasonably fast, as I think there are bytecode instructions that I would expect would be reasonably optimized. I'm not exactly sure whether to call these "heavy" or "light", because there isn't a point of comparison...
new Object();
I hear object creation these days is cheap. So I'll go with "light", if you're talking about the actual allocation. The performance of the entire statement, though, depends on what's going on in the constructor.
MyClass.doSomething();
Depends on whether the method has been inlined. If so, the it's as cheap as it gets. If not, then it's the cost of a vtable lookup, which may or may not be expensive. Not sure.
int i = 10;
Assigning a value/reference probably isn't expensive at all, since that's a decent amount of a program...
Related
In the following piece of code we make a call listType.getDescription() twice:
for (ListType listType: this.listTypeManager.getSelectableListTypes())
{
if (listType.getDescription() != null)
{
children.add(new SelectItem( listType.getId() , listType.getDescription()));
}
}
I would tend to refactor the code to use a single variable:
for (ListType listType: this.listTypeManager.getSelectableListTypes())
{
String description = listType.getDescription();
if (description != null)
{
children.add(new SelectItem(listType.getId() ,description));
}
}
My understanding is the JVM is somehow optimized for the original code and especially nesting calls like children.add(new SelectItem(listType.getId(), listType.getDescription()));.
Comparing the two options, which one is the preferred method and why? That is in terms of memory footprint, performance, readability/ease, and others that don't come to my mind right now.
When does the latter code snippet become more advantageous over the former, that is, is there any (approximate) number of listType.getDescription() calls when using a temp local variable becomes more desirable, as listType.getDescription() always requires some stack operations to store the this object?
I'd nearly always prefer the local variable solution.
Memory footprint
A single local variable costs 4 or 8 bytes. It's a reference and there's no recursion, so let's ignore it.
Performance
If this is a simple getter, the JVM can memoize it itself, so there's no difference. If it's a expensive call which can't be optimized, memoizing manually makes it faster.
Readability
Follow the DRY principle. In your case it hardly matters as the local variable name is character-wise as about as long as the method call, but for anything more complicated, it's readability as you don't have to find the 10 differences between the two expressions. If you know they're the same, so make it clear using the local variable.
Correctness
Imagine your SelectItem does not accept nulls and your program is multithreaded. The value of listType.getDescription() can change in the meantime and you're toasted.
Debugging
Having a local variable containing an interesting value is an advantage.
The only thing to win by omitting the local variable is saving one line. So I'd do it only in cases when it really doesn't matter:
very short expression
no possible concurrent modification
simple private final getter
I think the way number two is definitely better because it improves readability and maintainability of your code which is the most important thing here. This kind of micro-optimization won't really help you in anything unless you writing an application where every millisecond is important.
I'm not sure either is preferred. What I would prefer is clearly readable code over performant code, especially when that performance gain is negligible. In this case I suspect there's next to no noticeable difference (especially given the JVM's optimisations and code-rewriting capabilities)
In the context of imperative languages, the value returned by a function call cannot be memoized (See http://en.m.wikipedia.org/wiki/Memoization) because there is no guarantee that the function has no side effect. Accordingly, your strategy does indeed avoid a function call at the expense of allocating a temporary variable to store a reference to the value returned by the function call.
In addition to being slightly more efficient (which does not really matter unless the function is called many times in a loop), I would opt for your style due to better code readability.
I agree on everything. About the readability I'd like to add something:
I see lots of programmers doing things like:
if (item.getFirst().getSecond().getThird().getForth() == 1 ||
item.getFirst().getSecond().getThird().getForth() == 2 ||
item.getFirst().getSecond().getThird().getForth() == 3)
Or even worse:
item.getFirst().getSecond().getThird().setForth(item2.getFirst().getSecond().getThird().getForth())
If you are calling the same chain of 10 getters several times, please, use an intermediate variable. It's just much easier to read and debug
I would agree with the local variable approach for readability only if the local variable's name is self-documenting. Calling it "description" wouldn't be enough (which description?). Calling it "selectableListTypeDescription" would make it clear. I would throw in that the incremented variable in the for loop should be named "selectableListType" (especially if the "listTypeManager" has accessors for other ListTypes).
The other reason would be if there's no guarantee this is single-threaded or your list is immutable.
We were having this discussion wiht my colleagues about Inner assignments such as:
return result = myObject.doSomething();
or
if ( null == (point = field.getPoint()) )
Are these acceptable or should they be replaced by the following and why?
int result = myObject.doSomething();
return result;
or
Point point = field.getPoint();
if ( null == point)
The inner assignment is harder to read and easier to miss. In a complex condition it can even be missed, and can cause error.
Eg. this will be a hard to find error, if the condition evaluation prevent to assign a value to the variable:
if (i == 2 && null == (point = field.getPoint())) ...
If i == 2 is false, the point variable will not have value later on.
if ( null == (point = field.getPoint()) )
Pros:
One less line of code
Cons:
Less readable.
Doesn't restrict point's scope to the statement and its code block.
Doesn't offer any performance improvements as far as I am aware
Might not always be executed (when there is a condition preceding it that evaluates to false.
Cons outweigh pros 4 / 1 so I would avoid it.
This is mainly concerned with readablity of the code. Avoid inner assignments to make your code readable as you will not get any improvements with inner assignments
Functionally Not Necessarily.
For Readability Definitely Yes
They should be avoided. Reducing the number of identifiers/operations per line will increase readability and improve internal code quality. Here's an interesting study on the topic: http://dl.acm.org/citation.cfm?id=1390647
So bottom line, splitting up
return result = myObject.doSomething();
into
result = myObject.doSomething();
return result;
will make it easier for others to understand and work with your code. At the same time, it wouldn't be the end of the world if there were a couple inner assignments sprinkled throughout your code base, so long as they're easily understandable within their context.
Well, the first one is not exactly inner assignment but in second case...it reduces readability ...but in some cases like below,
while ( null == (point = field.getPoint()) );
it's good to write it this way
In both cases the first form is harder to read, and will make you want to change it whenever you want to inspect the value in a debugger. I don't know how often I've cursed "concise" code when step-debugging.
There are a very few cases where inner assignments reduce program complexity, for example in if (x != null && y != null && ((c = f(x, y)) > 0) {...} and you really only need the assignment in the case when it is executed in the complex condition.
But in most cases inner assignments reduce readability and they easily can be missed.
I think inner assignments are a relict to the first versions of the C programming language in the seventies, when the compilers didn't do any optimizations, and the work to optimize the code was left to the programmers. In that time inner assignments were faster, because it was not necessary to read the value again from the variable, but today with fast computers and optimizing compilers this point doesn't count any more. Nevertheless some C programmers were used to them. I think Sun introduced inner assignments to Java only because they wanted to be similar to C and make it easy for C programmers to change to Java.
Always work and aim for code readability not writeability. The same goes for stuff like a > b ? x : y;
There are probably many developers out there not having issues reading your first code snipet but most of them are used to the second snipet.
The more verbose form also makes it easier to follow in a Debugger such as Eclipse. I often split up single line assignments so the intermediate values are more easily visible.
Although not directly requested by OP a similar case is function calls as method arguments may save lines but are harder to debug:
myFunction(funcA(), funcB());
does not show the return types and is harder to step through. It's also more error-prone if the two values are of the same type.
I don't find any harm in using inner assignments. It saves few lines of code (though im sure it doesn't improve compiling or execution time or memory). The only drawback is that to someone else it might appear cumbersome.
Some people consider multiple return statements as bad programming style. While this is true for larger methods, I'm not sure if it is acceptable for short ones. But there is another question: Should else explicitly be written, if there is a return statement in the previous if?
Implicit else:
private String resolveViewName(Viewable viewable) {
if(viewable.isTemplateNameAbsolute())
return viewable.getTemplateName();
return uriInfo.getMatchedResources().get(0).getClass().toString();
}
Explicit else:
private String resolveViewName(Viewable viewable) {
if(viewable.isTemplateNameAbsolute())
return viewable.getTemplateName();
else
return uriInfo.getMatchedResources().get(0).getClass().toString();
}
Technically else is not necessary here, but it make the sense more obvious.
And perhaps the cleanest approach with a single return:
private String resolveViewName(Viewable viewable) {
String templateName;
if(viewable.isTemplateNameAbsolute())
templateName = viewable.getTemplateName();
else
templateName = uriInfo.getMatchedResources().get(0).getClass().toString();
return templateName;
}
Which one would you prefer? Other suggestions?
Other obvious suggestion: use the conditional operator.
private String resolveViewName(Viewable viewable) {
return viewable.isTemplateNameAbsolute()
? viewable.getTemplateName()
: uriInfo.getMatchedResources().get(0).getClass().toString();
}
For cases where this isn't viable, I'm almost certainly inconsistent. I wouldn't worry too much about it, to be honest - it's not the kind of thing where the readability is like to be significantly affected either way, and it's unlikely to introduce bugs.
(On the other hand, I would suggest using braces for all if blocks, even single statement ones.)
i prefer the cleanest approach with single return.To me code is readable, maintainable and not confusing.Tomorrow if you need to add some lines to the if or else block it is easy.
1.) code should never be clever.
The "single point of exit" dogma comes from the days of Structured Programming.
In its day, structured programming was a GOOD THING, especially as an alternative to the GOTO ridden spaghetti code that was prevalent in 1960's and 1970's vintage Fortran and Cobol code. But with the popularity of languages such as Pascal, C and so on with their richer range of control structures, Structured Programming has been assimilated into mainstream programming, and certain dogmatic aspects have fallen out of favor. In particular, most developers are happy to have multiple exits from a loop or method ... provided that it makes the code easier to understand.
My personal feeling is that in this particular case, the symmetry of the second alternative makes it easiest to understand, but the first alternative is almost as readable. The last alternative strikes me as unnecessarily verbose, and the least readable.
But #Jon Skeet pointed out that there is a far more significant stylistic issue with your code; i.e. the absence of { } blocks around the 'then' and 'else' statements. To me the code should really be written like this:
private String resolveViewName(Viewable viewable) {
if (viewable.isTemplateNameAbsolute()) {
return viewable.getTemplateName();
} else {
return uriInfo.getMatchedResources().get(0).getClass().toString();
}
}
This is not just an issue of code prettiness. There is actually a serious point to always using blocks. Consider this:
String result = "Hello"
if (i < 10)
result = "Goodbye";
if (j > 10)
result = "Hello again";
At first glance, it looks like result will be "Hello again" if i is less than 10 and j is greater than 10. In fact, that is a misreading - we've been fooled by incorrect indentation. But if the code had been written with { } 's around the then parts, it would be clear that the indentation was wrong; e.g.
String result = "Hello"
if (i < 10) {
result = "Goodbye";
}
if (j > 10) {
result = "Hello again";
}
As you see, the first } stands out like a sore thumb and tells us not to trust the indentation as a visual cue to what the code means.
I usually prefer the first option since it's the shortest.
And I think that any decent programmer should realize how it works without me having to write the else or using a single return at the end.
Plus there are cases in long methods where you might need to do something like
if(!isValid(input)) { return null; }// or 0, or false, or whatever
// a lot of code here working with input
I find it's even clearer done like this for these types of methods.
Depends on the intention. If the first return is a quick bail-out, then I'd go without the else; if OTOH it's more like a "return either this or that" scenario, then I'd use else. Also, I prefer an early return statement over endlessly nested if statements or variables that exist for the sole purpose of remembering a return value. If your logic were slightly complex, or even as it is now, I'd consider putting the two ways of generating the return value into dedicated functions, and use an if / else to call either.
I prefer multiple returns in an if-else structure when the size of both statements is about equal, the code looks more balanced that way. For short expressions I use the ternary operator. If the code for one test is much shorter or is an exceptional case, I might use a single if with the rest of the code remaining in the method body.
I try to avoid modifying variables as much as possible, because I think that makes the code much harder to follow than multiple exits from a method.
Keep the lingo consistent and readable for the lowest common denominated programmer who might have to revisit the code in the future.
Its only a few extra letters to type the else, and makes no difference to anything but legibility.
I prefer the first one.
Or... you can use if return else return for equally important bifurcations, and if return return for special cases.
When you have assertions (if p==null return null) then the first one is the most clear by far. If you have equally weighted options... I find fine to use the explicit else.
It's completely a matter of personal preference - I've literally gone through phases of doing all 4 of those option (including the one Jon Skeet posted) - none of them are wrong, and I've never experienced any drawbacks as a result of using either of them.
The stuff about only one return statement dates from the 1970s when Dijkstra and Wirth were sorting out structured programming. They applied it with great success to control structures, which have now settled down according to their prescription of one entry and one exit. Fortran used to have multiple entries to a subroutine (or possibly function, sorry, about 35 years since I wrote any), and this is a feature I've never missed, indeed I don't think I ever used it.
I've never actually encountered this 'rule' as applied to methods outside academia, and I really can't see the point. You basically have to obfuscate your code considerably to obey the rule, with extra variables and so on, and there's no way you can convince me that's a good idea. Curiously enough, if you write it the natural way as per your first option the compiler usually generates the code according to the rule anyway ... so you can argue that the rule is being obeyed: just not by you ;-)
Sure, people have a lot to say about programming style, but don't be so concerned about something relatively trivial to your program's purpose.
Personally, I like to go without the else. If anybody is going through your code, chances are high he won't be too confused without the else.
I prefer the second option because to me it is the quickest to read.
I would avoid the third option because it doesn't add clarity or efficiency.
The first option is fine too, but at least I would put a blank line between the first bit (the if and its indented return) and the second return statement.
In the end, it comes to down to personal preference (as so many things in programming style).
Considering multiple return statements "bad style" is a long, long discredited fallacy. They can make the code far clearner and more maintainable than explicit return value variables. Especially in larger methods.
In your example, I'd consider the second option the cleanest because the symmetrical structure of the code reflects its semantics, and it's shorter and avoids the unnecessary variable.
So say for example I'm going through an 'if' block and in this block, I am comparing the value of some number to a constant. Would it be more expensive like this:
if( foo.getOb().getVal() == CONST_0 )
{
....
}
....
if( foo.getOb().getVal() == _CONST_N )
{
....
}
else
....
OR:
int x = foo.getOb().getVal();
if( x == CONST_0 )
{
....
}
....
if( x == _CONST_N )
{
....
}
else
....
I know that this may seem like a stupid question. I think that the second implementation is fast/more efficient but I'm curious as to why. I've been trying to think of the reason for the last couple of minutes and can't really come up with anything since my knowledge on Java is...a bit lacking.
Thanks a lot for any answers!
It looks to me that you should be using a switch statement, in which case, you don't need to worry about it.
switch (foo.getOb().getVal()) {
case CONST_0:
....
break;
case CONST_N:
....
break;
default:
....
break;
}
This is not object creation. You are creating a reference to the object.
You are saving a few method-calls (in Java they are very efficient)
The difference is negligible. And It is not unlikely that the compiler will optimize such things.
Assuming getOb() and getVal() simply return references and don't do calculations, then these two snippets of code are functionally equivalent. Meaning that there is no real discernible difference between them.
Debating between which form to use comes down to a question of style and preference, and borders on pre-emptive optimization (in that you may spend a lot of time arguing about making a change which has zero measurable impact on your application's performance).
It really depends on how getObj() and getVal() are implemented. If they are expensive operations, then yes, your second example will almost always be faster. However, if you are concerned about the overhead of just the method call, don't be. The JIT compiler often can often times inline method calls, and even if it doesn't, there is very little overhead. Similiarly with the allocation on the heap for the local variable, these operations are very fast, and unless you've identified a performance "hotspot" through profiling, it's too early to start thinking of what's going to perform faster.
See here for more on premature optimization: When is optimisation premature?.
As a rule, write your code so it's easy to understand and correct first. And only if you've identified a clear bottleneck should you start trying to optimize for speed/memory. You will save yourself, and your colleagues that are trying to maintain/debug your code, time and frustration by writing for code clarity first.
The example code violates the Law of Demeter.
It should be
if( foo.isConst0() )
{
....
}
anyway. Also, premature optimization is the root of all evil
If "flag" is true I have to perform step no. 1 otherwise skip it. Is there a way out to skip this unnecessary repetitive check within the loop. (As the value of flag is not changing while the execution of the loop)
private void method(boolean flag) {
while (man > woman) {
if (flag) {
// Step no. 1
System.out.println(flag);
}
}
}
I'm not sure it is productive to worry about optimizations at this level. Generally it is more important to get the program working and move on to the next problem.
Having said that, there is an optimization called loop unswitching that some compilers will do for you. They duplicate the loop, once with and once without the conditional, and move the conditional outward to select the loop. (In your example you could make the entire loop conditional but I presume that's just an artifact of simplification for Stack Overflow.)
But this is just one more reason not to worry too much about optimizations, at least, not until you have a profile and you know that this region of code is responsible for detectable amounts of runtime.
Still, it's best to write code as cleanly as you can and puzzling through issues like this will teach you good things...
In fact, loop-invariant conditionals bother me too. I don't believe there is a general answer. There are fancy answers involving higher order functions or lambdas, "leave-it-to-the-compiler" answers, refactor-the-whole-outer-routine answers ... I would generally approve of whatever makes the code appear smaller. You have to prioritize in order to discriminate...
It depends on the scope of do. If do is always true, you don't need to check for it and you can remove if (do). There is no reason to set a variable to true if it will always be true. What is the scope?
If the value of do changes at any time in the loop, you have to check for it every time unless you rewrite the code so that the do == true state is handled outside the current loop (perhaps in a smaller loop; it depends on what you're trying to do [no pun intended]).
while (man > woman) {
Beware of infinite loops here :-)