Successive use of same method in block recalculates the method? - java

I've always assumed every time I call a method in Java the method is executed again. I've assumed the return value is not stored automatically unless I store it in a variable.
Then I ran across this code in Princeton's algs4.BST class where they call three methods twice each:
private boolean check() {
if (!isBST()) StdOut.println("Not in symmetric order");
if (!isSizeConsistent()) StdOut.println("Subtree counts not consistent");
if (!isRankConsistent()) StdOut.println("Ranks not consistent");
return isBST() && isSizeConsistent() && isRankConsistent();
}
Are they simply not concerned with performance? Or is the compiler smart enough keep the first return value of each method to use in the return statement?
Sorry if this is a duplicate seems like this answer should exist but I can't find it here or in Java docs. I found these (and others) but they don't answer my question:
Is this the cleanest way to repeat method call in Java?
How to call a method without repeat from other methods in java

The Java Language Specification explicitly and unconditionally states that evaluation of a method invocation expression involves executing the designated method's code. JLS 8 puts it this way:
At run time, method invocation requires five steps. First, a target
reference may be computed. Second, the argument expressions are
evaluated. Third, the accessibility of the method to be invoked is
checked. Fourth, the actual code for the method to be executed is
located. Fifth, a new activation frame is created, synchronization is
performed if necessary, and control is transferred to the method code.
(JLS 8, 15.12.4; emphasis added)
Thus, invoking a method a second time incurs its cost a second time, regardless of whether the same value can be expected to be computed. It is conceivable that JIT compilation could optimize that, but there are more considerations there than whether the same result is going to be computed, and you're anyway unlikely to see any JIT action triggered by just two invocations of a given method.
Bottom line: yes, the author of the code was simply not concerned with performance. They may have considered the implementation presented to be clearer than one that avoided redundant method invocations, or they may have had some other personal reason for the choice. This kind of disregard for practicalities is not uncommon in code serving academic purposes, such as that presented.

The check function in that code is only called in the context:
assert check();
Asserts are not normally enabled in production code, and if asserts are not enabled, the assert statement does absolutely nothing. So the check function will only be run in debugging runs. That fact does not give license to be arbitrarily inefficient, but it is common to make no attempt to optimize such code. The point of code run as an assertion is to be obviously and indisputably correct while it verifies an invariant, precondition or postcondition, and optimizations -- even trivial ones like saving a result in a local variable -- do not contribute to that goal.
##14.10. The assert Statement
An assertion is an assert statement containing a boolean expression. An assertion is either enabled or disabled. If an assertion is enabled, execution of the assertion causes evaluation of the boolean expression and an error is reported if the expression evaluates to false. If the assertion is disabled, execution of the assertion has no effect whatsoever.

Related

Memory/Performance differences of declaring variable for return result of method call versus inline method call

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

False postive for fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER?

SonarQube thinks the following code violates rule fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER (note, the code example is simplified and not logical):
class Foo {
boolean baz;
boolean foo() {
return bar() && baz==Baz.VALUE; //Violation of fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER
}
boolean bar() {
return baz == Baz.VALUE_2;
}
}
enum Baz {
VALUE, VALUE2
}
Performance - Method orders expressions in a conditional in a sub optimal way
(fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER)
This method builds a conditional expression, for example, in an if or while statement where the expressions contain both simple local variable comparisons, as well as comparisons on method calls. The expression orders these so that the method calls come before the simple local variable comparisons. This causes method calls to be executed in conditions when they do not need to be, and thus potentially causes a lot of code to be executed for nothing. By ordering the expressions so that the simple conditions containing local variable conditions are first, you eliminate this waste. This assumes that the method calls do not have side effects. If the method do have side effects, it is probably a better idea to pull these calls out of the condition and execute them first, assigning a value to a local variable. In this way you give a hint that the call may have side effects.
I think it's reasonable for the rule implementation to look inside the actual expression and if the content is a value check then not trigger a violation.
Is this a bug or am I missing something?
You almost gave the answer in your question already:
This causes method calls to be executed in conditions when they do not need to be, and thus potentially causes a lot of code to be executed for nothing. By ordering the expressions so that the simple conditions containing local variable conditions are first, you eliminate this waste.
FB-Contrib wants you to turn around the expression:
boolean foo() {
return baz==Baz.VALUE && bar();
}
This way, bar() needs to be executed only if baz==Baz.value. Of course this is something which the compiler or the JVM might optimize, so it would come down to a micro-benchmark to figure out if this precaution is actually necessary.
But it makes sense on a syntactical level, because calling a method is generally more expensive than a value check. So you don't need to look inside the method to tell that. Any guesses on the inlining behavior of the compiler / JVM are probably wrong anyway.

Is this a bug? (recursive constructors in Java)

I've been playing with recursive constructors in Java. The following class is accepted by the compiler two examples of recursive constructors in Java. It crashes with a StackOverflowError at runtime using java 1.7.0_25 and Eclipse Juno (Version: Juno Service Release 2 Build id: 20130225-0426).
class MyList<X> {
public X hd;
public MyList<X> tl;
public MyList(){
this.hd = null;
this.tl = new MyList<X>();
}
}
The error message makes sense, but I'm wondering if the compiler should catch it. A counterexample might be a list of integers with a constructor that takes an int as an argument and sets this.tl to null if the argument is less than zero. This seems reasonable to allow in the same way that recursive methods are allowed, but on the other hand I think constructors ought to terminate. Should a constructor be allowed to call itself?
So I'm asking a higher authority before submitting a Java bug report.
EDIT: I'm advocating for a simple check, like prohibiting a constructor from calling itself or whatever the Java developers did to address https://bugs.openjdk.java.net/browse/JDK-1229458. A wilder solution would be to check that the arguments to recursive constructor calls are decreasing with respect to some well-founded relation, but the point of the question is not "should Java determine whether all constructors terminate?" but rather "should Java use a stronger heuristic when compiling constructors?".
You could even have several constructors with different parameters, calling each other wiht this(...). In general, by computer science, a termination of code can not always be guaranteed. Some intelligence, like in this simple case, would be nice to have, but one may not require a compiler error. A bit like unreachable code. There is no difference between a constructor or normal method in my eyes however.
I wouldn't see any reason why a constructor should more need to terminate than any other kind of function. But, as with any other kind of function, the compiler cannot infer in the general case whether such function ever terminates (halting problem).
Now whether there's generally much need for a recursive constructor is debatable, but it certainly is not a bug, unless the Java specification would explicitly state that recursive constructor calls must result in an error.
And finally, it's important to differentiate between recursive calls to constructor(s) of the same object, which is a common pattern for instance to overcome the lack of default parameters, and calling the constructor of the same class to create another object, as done in your example.
Although this specific situation seems quite obvious, determining whether or not code terminates is an impossible question to answer.
If you try to configure compiler warnings for infinite recursion, you run into the Halting Problem:
"Given a description of an arbitrary computer program, decide whether
the program finishes running or continues to run forever."
Alan Turing proved in 1936 that a general algorithm to solve the
halting problem for all possible program-input pairs cannot exist.

Is there a zero-time, startup (no recompilation) switchable condition flag in Java?

I'm looking for a way to provide the fastest (I mean zero-time - compilation/classloading/JIT time resolved) possible On/Off flag for if condition. Of course this condition will be changed only once per application run - at startup.
I know that "compile-time constant if conditions" can be conditionaly compiled and whole condition can be removed from code. But what is the fastest (and possibly simple) alternative without need to recompile sources?
Can I move condition to separate .jar with single class & method with condition, where I produce two versions of that .jar and will swtich those versions in classpath on application startup? Will JIT remove call to method in separate .jar if it discovers, that method is empty?
Can I do it by providing two classes in classpath implementing "ClassWithMyCondition", where one of those class will have a real implementation and second will have just empty method and instantiate one of it by Class.forName and .newInstance()?Will JIT remove call to empty method from my primary very loop-nested method?
What can be simplest byte-code manipulation solution to this problem?
A standard way to do this sort of logic is to create an interface for the functionality you want, and then to create two (or more) implementations for that functionality. Only one of the implementations will be loaded in your runtime, and that implementation can make the assumptions it needs to in order to avoid the if condition entirely.
This has the advantage that each implementation is mutually exclusive, and things like the JIT compiler can ignore all the useless code for this particular run.
The simplest solution works here. Don't overcomplicate things for yourself.
Just put a final static boolean that isn't a compile-time constant (as defined in the JLS) somewhere and reference it wherever you want the "conditional" compilation. The JVM will evaluate it the first time it sees it, and by the time the code gets JIT'ed, the JVM will know that the value won't change and can then remove the check and, if the value is false, the block.
Some sources: Oracle has a wiki page on performance techniques which says to use constants when possible (note that in this context, the compiler is the JVM/JIT, and therefore a final field counts as a constant even if it isn't a compile-time constant by JLS standards). That page links to an index of performance tactics the JIT takes, which mentions techniques such as constant folding and flow-sensitive rewrites, including dead code removal.
You can pass custom values in the command line, and then check for that value once. So in your code, have something like this:
final static boolean customProp = "true".equalsIgnoreCase(System.getProperty("customProp"));
Depending on your command line parameters, the static final value will change. This will set the value to true:
java -DcustomProp="true" -jar app.jar
While this will set the value to false:
java -jar app.jar
This gives you the benefits of a static final boolean, but allows the value to be altered without recompiling.
[Edit]
As indicated in the comments, this approach does not allow for optimizations at compile time. The value of the static final boolean is set on classload, and is unchanged from there. "Normal" execution of the bytecode will likely need to evaluate every if (customProp). However, JIT happens at runtime, compiling bytecode down to native code. At this point, since the bytecode has the runtime value, more aggressive optimizations like inlining or excluding code are possible. Note that you cannot predict exactly if or when the JIT will kick in, though.
you should load the value from a properties file so that you can avoid having to recompile each time it cahnges. Simply update the text file and on next program run, it uses the new value. Here's an example I wrote a long time ago:
https://github.com/SnakeDoc/JUtils/blob/master/src/net/snakedoc/jutils/Config.java
The JIT recompiles the code every time you run it. You are doing this already whether you know it or not. This means if you have a field which the JIT believe is not changed (it doesn't even have to be final) it will be inlined and the check and code optimised away.
Trying to out smart the JIT is getting harder over time.

Java: Use getter vs caching value

I have a getter that returns a String and I am comparing it to some other String. I check the returned value for null so my ifstatement looks like this (and I really do exit early if it is true)
if (someObject.getFoo() != null && someObject.getFoo().equals(someOtherString)) {
return;
}
Performancewise, would it be better to store the returned String rather than calling the getter twice like this? Does it even matter?
String foo = someObject.getFoo();
if (foo != null && foo.equals(someOtherString)) {
return;
}
To answer questions from the comments, this check is not performed very often and the getter is fairly simple. I am mostly curious how allocating a new local variable compares to executing the getter an additional time.
It depends entirely on what the getter does. If it's a simple getter (retrieving a data member), then the JVM will be able to inline it on-the-fly if it determines that code is a hot spot for performance. This is actually why Oracle/Sun's JVM is called "HotSpot". :-) It will apply aggressive JIT optimization where it sees that it needs it (when it can). If the getter does something complex, though, naturally it could be slower to use it and have it repeat that work.
If the code isn't a hot spot, of course, you don't care whether there's a difference in performance.
Someone once told me that the inlined getter can sometimes be faster than the value cached to a local variable, but I've never proven that to myself and don't know the theory behind why it would be the case.
Use the second block. The first block will most likely get optimized to the second anyway, and the second is more readable. But the main reason is that, if someObject is ever accessed by other threads, and if the optimization somehow gets disabled, the first block will throw no end of NullPointerException exceptions.
Also: even without multi-threading, if someObject is by any chance made volatile, the optimization will disappear. (Bad for performance, and, of course, really bad with multiple threads.) And lastly, the second block will make using a debugger easier (not that that would ever be necessary.)
You can omit the first null check since equals does that for you:
The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
So the best solution is simply:
if(someOtherString.equals(someObject.getFoo())
They both look same,even Performance wise.Use the 1st block if you are sure you won't be using the returned value further,if not,use 2nd block.
I prefer the second code block because it assigns foo and then foo cannot change to null/notnull.
Null are often required and Java should solve this by using the 'Elvis' operator:
if (someObject.getFoo()?.equals(someOtherString)) {
return;
}

Categories

Resources