Sometimes i extract boolean checks into local variables to achief better readability.
What do you think?
Any disadvantages?
Does the compiler a line-in or something if the variable isn't used anywhere else? I also thought about reducing the scope with an additional block "{}".
if (person.getAge() > MINIMUM_AGE && person.getTall() > MAXIMUM_SIZE && person.getWeight < MAXIMUM_WEIGHT) {
// do something
}
final boolean isOldEnough = person.getAge() > MINIMUM_AGE;
final boolean isTallEnough = person.getTall() > MAXIMUM_SIZE;
final boolean isNotToHeavy = person.getWeight < MAXIMUM_WEIGHT;
if (isOldEnough && isTallEnough && isNotToHeavy) {
// do something
}
I do this all the time. The code is much more readable that way. The only reason for not doing this is that it inhibits the runtime from doing shortcut optimisation, although a smart VM might figure that out.
The real risk in this approach is that it loses responsiveness to changing values.
Yes, people's age, weight, and height don't change very often, relative to the runtime of most programs, but they do change, and if, for example, age changes while the object from which your snippet is still alive, your final isOldEnough could now yield a wrong answer.
And yet I don't believe putting isEligible into Person is appropriate either, since the knowledge of what constitutes eligibility seems to be of a larger scope. One must ask: eligible for what?
All in all, in a code review, I'd probably recommend that you add methods in Person instead.
boolean isOldEnough (int minimumAge) { return (this.getAge() > minimumAge); }
And so on.
Your two blocks of code are inequivalent.
There are many cases that could be used to show this but I will use one. Suppose that person.getAge() > MINIMUM_AGE were true and person.getTall() threw an exception.
In the first case, the expression will execute the if code block, while the second case will throw an exception. In computability theory, when an exception is thrown, then this is called 'the bottom element. It has been shown that a program when evaluated using eager evaluation semantics (as in your second example), that if it terminates (does not resolve to bottom), then it is guaranteed that an evaluation strategy of laziness (your first example) is guaranteed to terminate. This is an important tenet of programming. Notice that you cannot write Java's && function yourself.
While it is unlikely that your getTall() method will throw an exception, you cannot apply your reasoning to the general case.
I think the checks probably belong in the person class. You could pass in the Min/Max values, but calling person.IsEligable() would be a better solution in my opinion.
You could go one step further and create subtypes of the Person:
Teenager extends Person
ThirdAgePerson extends Person
Kid extends Person
Subclasses will be overriding Person's methods in their own way.
One advantage to the latter case is that you will have the isOldEnough, isTallEnough, and isNotToHeavy (sic) variables available for reuse later in the code. It is also more easily readable.
You might want to consider abstracting those boolean checks into their own methods, or combining the check into a method. For example a person.isOldEnough() method which would return the value of the boolean check. You could even give it an integer parameter that would be your minimum age, to give it more flexible functionality.
I think this is a matter of personal taste. I find your refactoring quite readable.
In this particualr case I might refactor the whole test into a
isThisPersonSuitable()
method.
If there were much such code I might even create a PersonInterpreter (maybe inner) class which holds a person and answers questions about their eligibility.
Generally I would tend to favour readability over any minor performance considerations.
The only possible negative is that you lose the benefits of the AND being short-circuited. But in reality this is only really of any significance if any of your checks is largely more expensive than the others, for example if person.getWeight() was a significant operation and not just an accessor.
I have nothing against your construct, but it seems to me that in this case the readability gain could be achieved by simply putting in line breaks, i.e.
if (person.getAge() > MINIMUM_AGE
&& person.getTall() > MAXIMUM_SIZE
&& person.getWeight < MAXIMUM_WEIGHT)
{
// do something
}
The bigger issue that other answers brought up is whether this belongs inside the Person object. I think the simple answer to that is: If there are several places where you do the same test, it belongs in Person. If there are places where you do similar but different tests, then they belong in the calling class.
Like, if this is a system for a site that sells alcohol and you have many places where you must test if the person is of legal drinking age, then it makes sense to have a Person.isLegalDrinkingAge() function. If the only factor is age, then having a MINIMUM_DRINKING_AGE constant would accomplish the same result, I guess, but once there's other logic involved, like different legal drinking ages in different legal jurisdictions or there are special cases or exceptions, then it really should be a member function.
On the other hand, if you have one place where you check if someone is over 18 and somewhere else where you check if he's over 12 and somewhere else where you check if he's over 65 etc etc, then there's little to be gained by pushing this function into Person.
Related
Are there any performance or memory differences between the two snippets below? I tried to profile them using visualvm (is that even the right tool for the job?) but didn't notice a difference, probably due to the code not really doing anything.
Does the compiler optimize both snippets down to the same bytecode? Is one preferable over the other for style reasons?
boolean valid = loadConfig();
if (valid) {
// OK
} else {
// Problem
}
versus
if (loadConfig()) {
// OK
} else {
// Problem
}
The real answer here: it doesn't even matter so much what javap will tell you how the corresponding bytecode looks like!
If that piece of code is executed like "once"; then the difference between those two options would be in the range of nanoseconds (if at all).
If that piece of code is executed like "zillions of times" (often enough to "matter"); then the JIT will kick in. And the JIT will optimize that bytecode into machine code; very much dependent on a lot of information gathered by the JIT at runtime.
Long story short: you are spending time on a detail so subtle that it doesn't matter in practical reality.
What matters in practical reality: the quality of your source code. In that sense: pick that option that "reads" the best; given your context.
Given the comment: I think in the end, this is (almost) a pure style question. Using the first way it might be easier to trace information (assuming the variable isn't boolean, but more complex). In that sense: there is no "inherently" better version. Of course: option 2 comes with one line less; uses one variable less; and typically: when one option is as readable as another; and one of the two is shorter ... then I would prefer the shorter version.
If you are going to use the variable only once then the compiler/optimizer will resolve the explicit declaration.
Another thing is the code quality. There is a very similar rule in sonarqube that describes this case too:
Local Variables should not be declared and then immediately returned or thrown
Declaring a variable only to immediately return or throw it is a bad practice.
Some developers argue that the practice improves code readability, because it enables them to explicitly name what is being returned. However, this variable is an internal implementation detail that is not exposed to the callers of the method. The method name should be sufficient for callers to know exactly what will be returned.
https://jira.sonarsource.com/browse/RSPEC-1488
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.
Class A
Class A {
public HashMap <Integer,Double> myHashMap;
public A(){
myHashMap = new HashMap()
}
}
class B
Class B {
private A anInstanceOfA;
public B(A a) {
this.anInstanceOfA = a;
}
aMethod(){
anInstanceOfA.myHashMap.get(1); <--getting hashmap value for key = 1
//proceed to use this value, but instead of storing it to a variable
// I use anInstanceOfA.myHashMap.get(1) each time I need that value.
}
In aMethod() I use anInstanceOfA.myHashMap.get(1) to get the value for key = 1. I do that multiple times in aMethod() and I'm wondering if there is any difference in efficiency between using anInstanceOfA.myHashMap.get(1) multiple times or just assigning it to a variable and using the assigned variable multiple times.
I.E
aMethod(){
theValue = anInstanceOfA.myHashMap.get(1);
//proceed to use theValue in my calculations. Is there a difference in efficiency?
}
In theory the JVM can optimise away the difference to be very small (compared to what the rest of the program is doing). However I prefer to make it a local variable as I believe it makes the code clearer (as I can give it a meaningful name)
I suggest you do what you believe is simpler and clearer, unless you have measured a performance difference.
The question seems to be that you want to know if it is more expensive to call get(l) multiple times instead of just once.
The answer to this is yes. The question is if it is enough to matter. The definitive answer is to ask the JVM by profiling. You can, however, guess by looking at the get method in your chosen implementation and consider if you want to do all that work every time.
Note, that there is another reason that you might want to put the value in a variable, namely that you can give it a telling name, making your program easier to maintain in the future.
This seems like a micro-optimization, that really doesn't make much difference in the scheme of things.
As #peter already suggested, 'optimizing' for style/readability is a better rationale for choosing the second option over the first one. Optimizing for speed only starts making sense if you really do a lot of calls, or if the call is very expensive -- both are probably not the case in your current example.
Put it in a local variable, for multiple reasons:
It will be much faster. Reading a local variable is definitely cheaper than a HashMap lookup, probably by a factor of 10-100x.
You can give the local variable a good, meaningful name
Your code will probably be shorter / simpler overall, particularly if you use the local variable many times.
You may get bugs during future maintenance if someone modifies one of the get calls but forgets to change the others. This is a problem whenever you are duplicating code. Using a local variable minimises this risk.
In concurrent situations, the value could theoretically change if the HashMap is modified by some other code. You normally want to get the value once and work with the same value. Although if you are running into problems of this nature you should probably be looking at other solutions first (locking, concurrent collections etc.)
I commonly find myself writing code like this:
private List<Foo> fooList = new ArrayList<Foo>();
public Foo findFoo(FooAttr attr) {
for(Foo foo : fooList) {
if (foo.getAttr().equals(attr)) {
return foo;
}
}
}
However, assuming I properly guard against null input, I could also express the loop like this:
for(Foo foo : fooList) {
if (attr.equals(foo.getAttr()) {
return foo;
}
}
I'm wondering if one of the above forms has a performance advantage over the other. I'm well aware of the dangers of premature optimization, but in this case, I think the code is equally legible either way, so I'm looking for a reason to prefer one form over another, so I can build my coding habits to favor that form. I think given a large enough list, even a small performance advantage could amount to a significant amount of time.
In particular, I'm wondering if the second form might be more performant because the equals() method is called repeatedly on the same object, instead of different objects? Maybe branch prediction is a factor?
I would offer 2 pieces of advice here:
Measure it
If nothing else points you in any given direction, prefer the form which makes most sense and sounds most natural when you say it out loud (or in your head!)
I think that considering branch prediction is worrying about efficiency at too low of a level. However, I find the second example of your code more readable because you put the consistent object first. Similarly, if you were comparing this to some other object that, I would put the this first.
Of course, equals is defined by the programmer so it could be asymmetric. You should make equals an equivalence relation so this shouldn't be the case. Even if you have an equivalence relation, the order could matter. Suppose that attr is a superclass of the various foo.getAttr and the first test of your equals method checks if the other object is an instance of the same class. Then attr.equals(foo.getAttr()) will pass the first check but foo.getAttr().equals(attr) will fail the first check.
However, worrying about efficiency at this level seldom has benefits.
This depends on the implementation of the equals methods. In this situation I assume that both objects are instances of the same class. So that would mean that the methods are equal. This makes no performance difference.
If both objects are of the same type, then they should perform the same. If not, then you can't really know in advance what's going to happen, but usually it will be stopped quite quickly (with an instanceof or something else).
For myself, I usually start the method with a non-null check on the given parameter and I then use the attr.equals(foo.getAttr()) since I don't have to check for null in the loop. Just a question of preference I guess.
The only thing which does affect performance is code which does nothing.
In some cases you have code which is much the same or the difference is so small it just doesn't matter. This is the case here.
Where its is useful to swap the .equals() around is when you have a known value which cannot be null (This doesn't appear to be the cases here) of the type you are using is known.
e.g.
Object o = (Integer) 123;
String s = "Hello";
o.equals(s); // the type of equals is unknown and a virtual table look might be required
s.equals(o); // the type of equals is known and the class is final.
The difference is so small I wouldn't worry about it.
DEVENTER (n) A decision that's very hard to make because so little depends on it, such as which way to walk around a park
-- The Deeper Meaning of Liff by Douglas Adams and John Lloyd.
The performance should be the same, but in terms of safety, it's usually best to have the left operand be something that you are sure is not null, and have your equals method deal with null values.
Take for instance:
String s1 = null;
s1.equals("abc");
"abc".equals(s1);
The two calls to equals are not equivalent as one would issue a NullPointerException (the first one), and the other would return false.
The latter form is generally preferred for comparing with string constants for exactly this reason.
I prefer to use local variables rather than multiple calls to the same method.
/*
* I prefer this
*/
Vehicle vehicle = person.getVehicle()
if (vehicle instanceof Car) {
Car car = (Car) vehicle;
car.openSunroof();
} else if (vehicle instanceof Bike) {
Bike bike = (Bike) vehicle;
bike.foldKickstand();
}
/*
* Rather than this
*/
if (person.getVehicle() instanceof Car) {
Car car = (Car) person.getVehicle();
car.openSunroof();
} else if (person.getVehicle() instanceof Bike) {
Bike bike = (Bike) person.getVehicle();
bike.foldKickstand();
}
I believe that the first way is going to perform a tiny bit faster
I think the second way violates the DRY principle
I find the first way more readable and easier to debug (... OK negligible because I could step over)
I don't want to have to deal with the possibility of changed object state
Which do you prefer and why?
I prefer the first version for all the reasons you've mentioned. In particular (just to spell out your fourth point), it means you're definitely going to get consistent results... you could get horribly nasty results with the second version if getVehicle() returned a Car on the first call, then a Bike on the second...
The performance side doesn't bother me (I'll happily call List.size() repeatedly, for example) but readability, consistency and non-repeating are all much more important. Essentially the first snippet conveys the idea of "get a value, then use it" much more effectively than the second does.
So yes, I'm with you... is anyone recommending the second form to you?
Yeah the first one is definitely better. I would never go for the second method.
But you should think of using polymorphism more. Relying on instanceof so heavyly is not good OO design.
I normally dislike the introduction of extra variables as every bit of added state makes a method more complex. But even I'd say that it's warranted in your example since the variable replaces 4 repetitions of identical code.
But the variable should definitely be final!
I agree, but I also try to reduce use of 'instanceof' too, at the class design level.
I personally think the first one is cleaner. However, provided the called method is not something computation intensive, it doesn't matter much.
Probably the second is a bit faster (if you use Java 1.6) because in the first example you make a copy of the variable, while the java VM will be likely to inline the function call in both examples. Of course optimization is never an argument with calls like this. The compiler does so many optimizations that we shouldn't bother (often it'll just reduce the speed because we dont' know it well enough).
As everybody that answered this question so far, I definitely prefer the first style. It can be even cleaner though:
Vehicle vehicle = person.getVehicle()
if (vehicle instanceof Car) {
((Car) vehicle).openSunroof();
} else if (vehicle instanceof Bike) {
((Bike) vehicle).foldKickstand();
}
Both examples need some work. Try to push the behavior into an abstract (or protected) method on Vehicle. If this is code you can't modify, use composition to put it inside of an interface in your code base so that you don't have to pollute the rest of your code with the poor design of the library you're using. This is definitely a code smell. See "Replace Conditional with Polymorphism" in Fowler's Refactoring book.