So i've been lurking around here for the past few years and have finally come to the situation where I did NOT find an existing answer here. The question itself is pretty simple though.
Assume the following statement (no language specific syntax):
var result = fetchFromDb() == null ? defaultValue : fetchFromDb().property;
What I want to know is: does the compiler in Java or C# have a way to optimise this statement or will there really be two calls to the fetchFromDb() method meaning two DB access calls, two execution plans and so on?
I already have tested this in Java and found out that the method is called twice, but I have no idea about eventual caching in the background or anything alike.
So: is using the ternary conditional with methods a bad practice? Is there a way to cache the value compared against inline in order to preserve the beauty of this style?
Yes, it will always be two calls. The fact is between the first call and the second call, the result of fetchFromDb() can change. There is no way for the compiler to predict that change in value, unless it is a well known deterministic function. Deterministic being the key word here. Even then there may not be compiler optimization for such things.
Using a ternary condition with methods is not bad practice per se, but it is less readable than a simple if statement.
The only way to guarantee a single call is to code a single call.
var result;
var fetchResult = fetchFromDb();
if (fetchResult == null) {
result = defaultValue;
} else {
result = result.property;
}
Or if you insist on using a ternary
var fetchResult = fetchFromDb()
var result = (fetchResult == null) ? defaultValue : result.property;
I really think this is much clearer than a ternary. Having code on a single line does not infer beautiful code.
Actually
var result = fetchFromDb() == null ? defaultValue : fetchFromDb().property;
Will make two calls in the else case. To avoid the double call:
var fetch = fetchFromDb();
var result = fetch != null ? fetch.property : defaultValue;
Related
I am using this code:
A a = aMap.contains(key) ? aMap.get(key) : createAExpensively(key);
I believe that Java is lazy so if aMap.contains(key)) then the createAExpensively() function is never called.
Then, I stumbled onto the Map.getOrDefault() method. If we instead use:
A a = aMap.getOrDefault(key, createAExpensively(key));
is Java still lazy in calling the createAExpensively() function?
It seems that Java will first create the object A and pass it as a method parameter, based on this question, but I'm not totally sure.
If Java is not lazy when using Map.getOrDefault(), what is the point of that method?
Is Java still lazy in calling the createAExpensively() function?
[in .getOrDefault(key, createAExpensively(key))]
Function parameters are evaluated (from left to right) before actually calling the function. So createAExpensively(key) will be evaluated before calling getOrDefault. This behavior is also known as applicative order evaluation strategy.
If Java is not lazy when using Map.getOrDefault(), what is the point of that method?
It's useful when the default value is not expensive to create,
for example when it's an already computed value or constant.
In that case the Map.getOrDefault(...) call allows a more compact syntax than the ternary operator.
If the default value is expensive to compute,
and if you actually want to put the computed value in the map,
then as of Java 8,
you can use computeIfAbsent:
A a = aMap.computeIfAbsent(key, k -> createAExpensively(k));
Java is not lazy at all. You are using conditional operator to check whether aMap.contains(key). If this is true it will never call createAExpensively(key) but aMap.get(key)
It isn't lazy in that case.
The point of the method is that there's lots of times when the default is a constant or something you've already computed anyway. For example, you might use getOrDefault(key, 0) when you're getting some kind of count and absent keys should be counted as zeroes.
This is called "short-circuit evaluation" rather than lazy evaluation: The JVM is not deferring evaluation of createExpensively(), but rather avoiding it completely if it's not necessary, i.e if the condition holds.
See also the answer to the following question here on StackOverflow:
Java logical operator short-circuiting
It is not lazy at all.
This code
A a = aMap.contains(key) ? aMap.get(key) : createAExpensively(key);
evaulates to
if (aMap.contains(key))
{
a = aMap.get(key);
}
else
{
a = createAExpensively(key);
}
Will java actually call all three functions at runtime if one of them does not return true?
Often for debugging purposes, I like to see the result of these conditional checks in the debugger and putting them in one line makes that much more difficult. If there are half a dozen checks, then the code gets to be more unreadable.
boolean result1 = CheckSomething();
boolean result2 = CheckSomethingElse();
boolean result3 = CheckSomeOtherThing();
boolean finalResult = result1 && result2 && result3;
If Java doesn't optimize this conditional at runtime, then better performance should be achieved by writing the code like this at a cost of not being able to easily see the intermediary values in the debugger.
boolean finalResult = CheckSomething() && CheckSomethingElse() && CheckSomeOtherThing();
In general your code snippets are not equivalent. The first version must behave as-if all functions are called since you call them unconditionally in your code.
The second version of your code:
boolean finalResult = CheckSomething() && CheckSomethingElse() && CheckSomeOtherThing();
is not equivalent because the && operation is shortcut, so the remaining functions will not be called if any returns false.
When running in the interpreter, you can expect that the first version of your code will actually call all the methods.
Now, the interesting part: after the code is compiled, the compiler is now able to "look into" the various functions determine that they are pure functions, without side effects, and it may compile the two versions identically. In fact, if the functions are very simple, it may be better to compile both versions to always call all three functions, since combining three boolean results and checking it once may be much faster if any of the results are unpredictable.
The compiler may not always be able to determine whether a function has side effects, or there may actually be side effects that only you know don't matter (e.g., an ArrayOutOfBoundsException that you know won't occur but the compiler can't prove). So it's generally better to write the second form, which allows to compiler to use short-circuit evaluation regardless of what it is able to prove about the functions.
You can write this:
boolean result1 = condition1();
boolean result2 = result1 && condition2();
boolean result3 = result2 && condition3();
This allows you to step through each condition, and to see the intermediate results without executing unnecessary code.
You can also set a single breakpoint after the result3 line, which shows you the first result that returned false.
Agreed, that the second example will keep evaluating until it reaches a false condition, then it will return "false". The short circuit operator && is being used, therefore once a false condition is encountered, evaluation stops.
I have the following scenario.. and I come across the similar scenario many a times. Which is more preferable of the following two options?
Option-1:
String result = ( getDetails(...) == null ) ? "" : getDetails(...);
Option-2:
String returnValue = getDetails(...);
String result = ( returnValue == null ) ? "" : returnValue;
Which is more preferable and/or a good practice.?
Imho The second one is better because it's avoiding calling getDetails(...) method twice.
If you have to do that check for every call of getDetails then the best way would be getDetails method to return "" in cases when you return null.
Also calling the same method twice (which is probably idempotent in your case) is not a good practice even if it is very simple.
Please read this java-how-expensive-is-a-method-call. Main idea is don't do premature optimization, but you should get used to these simple cases when you can write better code
Option-2: is better
Option-1: Results in extra method call and such cases should always be avoided unless getDetails(...) is a getter method (a one liner method which returns something)
If you dig down to micro optimization, a method call generally results in
allocation of stack for the method variables
jumping the instruction set
which are couple of many overheads. As many say, such performance optimization should be left to Compiler and the code should be written to be more readable.
I'd prefer the second option because it is more readable, especially when using the ternary operator.
If it is a problem or not to call getDetails(...) twice depends on your method. If it is a simple getter, the JVM might optimize the call and directly use the value so storing it in a local variable does not make a difference.
If it is a more complex method, e.g. a query to the database, I would definitely store the result in a local variable.
Generally speaking: Care about code readability first! If you find performance problems later on, try optimizing then.
option-2 will be always optimized one what ever you wrote in the calling function.
Even if you are writing any in-build function or expression two times it will take fraction of section more than option-2.
In a project I've been trying to familiarise myself with, I ran across a method that looks like this:
public boolean testString(String string){
return string != null && !"".equals(string);
}
What is the value of testing the string for emptiness this way instead of with the variable first? I understand why we see constant-first (Yoda syntax) in C, but is there any reason to do so with method calls in Java?
note: I do understand about NullPointerException, which is not possible in this instance. I'm looking for a value to doing it this way in this case particularly.
In this context it makes little difference, as it already tested for null. Usually you do it this way to make sure you don't call a member on a null-reference (resulting in a NullPointerException), i.e.
"test".equals(myString)
will never throw a null pointer exception whereas
myString.equals("test")
will if myString is null. So basically, the first test makes sure it's a string (not null) AND it's equal to "test".
For two strings it doesn't matter much, but when there is a non-final type involved it can be a micro-optimization.
If the left hand side is a non-overridden concrete type, then the dispatch becomes static.
Consider what the JIT has to do for
Object o;
String s;
o.equals(s)
vs
s.equals(o)
In the first, the JIT has to find the actual equals method used, whereas in the second, it knows that it can only by String.equals.
I adopted the habit of doing
"constant value" == variableName
in other languages, since it means that the code will fail to parse if I mis-type = instead of ==.
And when I learned Java, I kept that order preference.
The usual reason for using "constant string".equals(variable) is that this works properly even if variable is null (unlike variable.equals("constant string")). In your case, however, since you are testing that string != null in a short-circuit boolean test, it's entirely a matter of style (or habit).
If they just did this:
!"".equals(string);
then they're avoiding the possibility of a NullPointerException, which is pretty smart. However, they're checking for null right before this condition, which is technically not necessary.
Is it running any tools like checkstyle? if it is, putting the variable first will result in checkstyle failing. Another reason is that if you put the empty string first it will take away the possibility of getting a null exception if the variable is null because the expression will always evaluate to false. If you had the variable first and the variable was null it will throw an exception.
It is more than a coder preference. If the purpose of the method was only to check that string is not an empty String (without caring whether its a null) then it makes sense to have the constant first to avoid a NullPointerException.
e.g. This method will return the boolean outcome. false in case string is null.
public boolean testString(String string){
return !"".equals(string);
}
while this one may throw a runtime exception if string is null
public boolean testString(String string){
return !string.equals("");
}
No, it is unnatural, and harder to read. It triggers a pause for most readers, and may wastefully consume lots of resources on stackoverlow.com.
(Better use string.isEmtpy() anyway)
There are no fixed rules tho, sometime this is easier to read
if( null != foobar(blahblahblah, blahblahblah, blahblahblah) )
than
if( foobar(blahblahblah, blahblahblah, blahblahblah) != null )
This question can be answered on a number of levels:
What does the example mean?
As other answers have explained, !"".equals(str) tests if str is an non-empty string. In general, the <stringLiteral>.equals(str) idiom is a neat way of testing a string that deals with the null case without an explicit test. (If str is null then the expression evaluates to false.
Is this particular example best practice?
In general no. The !"".equals(str) part deals with the case where str is null, so the preceding null test is redundant.
However, if str was null in the vast majority of cases, this usage would possibly be faster.
What is a better way to do this from a code-style perspective?
return "".equals(str);
or
return str != null && !str.isEmpty();
However, the second approach doesn't work with Java versions prior to 1.6 ... because isEmpty() is a recent API extension.
What is the optimal way to do this?
My gut feeling is that return str != null && !str.isEmpty(); will be fastest. The String.isEmpty() method is implemented as a one-line test, and is small enough that the JIT compiler will inline it. The String.equals(Object) method is a lot more complicated, and too big to be inlined.
Miško Hevery (see his videos on youtube) calls this type of overkill "paranoid programming" :-)
Probably in this video:
http://www.youtube.com/watch?v=wEhu57pih5w
See also here: http://misko.hevery.com/2009/02/09/to-assert-or-not-to-assert/
I asked this goofy question earlier today and got good answers. I think what I really meant to ask is the following:
String aString = ""; // Or = null ?
if(someCondition)
aString = "something";
return aString;
In this case, the string has to be initialized in order to return it. I always thought that either option (setting it to "" or to null looks kind of ugly. I was just wondering what others do here...or is it more of just a matter of whether you want empty string or null being passed around in your program (and if you are prepared to handle either)?
Also assume that the intermediary logic is too long to cleanly use the conditional (? :) operator.
return (someCondition) ? "something" : "";
or
return (someCondition) ? "something" : null;
Typically though if your function says it will return a String I prefer to actually return a String instead of a null. Either way the calling function should probably check for both cases.
depends on what you want to achieve,
in general i would return null to signal that nothing was processed,
it might later pop up cases where someCondition is true but the string you build together is "" anyway, that way you can differentiate from that case if you return null if nothing was processed.
i.e.
String aString = null;
if(someCondition)
aString = "something";
return aString;
but it all really depends on what you want to achieve...
e.g. if the code is suppose to build together a string that is delivered directly in the UI you would go for "" instead
In this case it might be best to do something like:
public void func() {
boolean condition = getConditionFromSomewhere();
String condString = getAppropriateValue(condition);
}
public String getAppropriateValue(boolean condition) {
if (condition) {
return "something";
} else {
return "somethingElse";
}
}
It may seem a bit overkill for a boolean condition, but if you get into more complex conditions (more choices, like enums and the like), it would nicely abstract that logic away. And with a descriptive method name make it almost self-documenting to boot.
Since you're asking our opinions...
I'm a bit overconscious about quality. I prefer that all my "if" statements have an "else", because (1) it helps to understand the code if there are multiple nested "if's", (2) force me to consider the possibility (what should happen if the condition is false?).
Regarding reason (1), I prefer to avoid nested if's, but sometimes you inherit code with a lot of if's.
if(someCondition)
aString = "something";
else
aString = "";
I would prefer "null", because it would make the app fail and dump a stack that I can follow. An empty string, in contrast, would keep things going. Naturally, it depends on the logic of your code what is better: null or "".
Yes, this is just a matter of whether you want a null or an empty string being passed around in your program. If you plan to append things to it later, and the someCondition just indicates that you should give it a first value to begin with, then use the empty string. If you plan to have it indicate that there is a string or there is nothing, then perhaps using null is better.
Its just your preference of what your api should do. If you are returning null, there may be a chance that the api users can get NPE if they are not checking for null. But if you are using "" string, the error may pass silently if it is not supposed to be null. It is a preference of how you write your api and depends on the use case.
Thinking about it, I rarely use "" in code for any purpose.