Since JDK 7 I've been happily using the method it introduced to reject null values which are passed to a method which cannot accept them:
private void someMethod(SomeType pointer, SomeType anotherPointer) {
Objects.requireNonNull(pointer, "pointer cannot be null!");
Objects.requireNonNull(anotherPointer, "anotherPointer cannot be null!");
// Rest of method
}
I think this method makes for very tidy code which is easy to read, and I'm trying to encourage colleagues to use it. But one (particularly knowledgeable) colleague is resistant, and says that the old way is more efficient:
private void someMethod(SomeType pointer, SomeType anotherPointer) {
if (pointer == null) {
throw new NullPointerException("pointer cannot be null!");
}
if (anotherPointer == null) {
throw new NullPointerException("anotherPointer cannot be null!");
}
// Rest of method
}
He says that calling requireNonNull involves placing another method on the JVM call stack and will result in worse performance than a simple == null check.
So my question: is there any evidence of a performance penalty being incurred by using the Objects.requireNonNull methods?
Let's look at the implementation of requireNonNull in Oracle's JDK:
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
So that's very simple. The JVM (Oracle's, anyway) includes an optimizing two-stage just-in-time compiler to convert bytecode to machine code. It will inline trivial methods like this if it can get better performance that way.
So no, not likely to be slower, not in any meaningful way, not anywhere that would matter.
So my question: is there any evidence of a performance penalty being incurred by using the Objects.requireNonNull methods?
The only evidence that would matter would be performance measurements of your codebase, or of code designed to be highly representative of it. You can test this with any decent performance testing tool, but unless your colleague can point to a real-world example of a performance problem in your codebase related to this method (rather than a synthetic benchmark), I'd tend to assume you and he/she have bigger fish to fry.
As a bit of an aside, I noticed your sample method is a private method. So only code your team is writing calls it directly. In those situations, you might look at whether you have a use case for assertions rather than runtime checks. Assertions have the advantage of not executing in "released" code at all, and thus being faster than either alternative in your question. Obviously there are places you need runtime checks, but those are usually at gatekeeping points, public methods and such. Just FWIW.
Formally speaking, your colleague is right:
If someMethod() or corresponding trace is not hot enough, the byte code is interpreted, and extra stack frame is created
If someMethod() is called on 9-th level of depth from hot spot, the requireNonNull() calls shouldn't be inlined because of MaxInlineLevel JVM Option
If the method is not inlined for any of the above reasons, argument by T.J. Crowder comes into play, if you use concatenation for producing error message
Even if requireNonNull() is inlined, JVM wastes time and space for performing this.
On the other hand, there is FreqInlineSize JVM option, which prohibits inlining too big (in bytecodes) methods. The method's bytecodes is counted by themselves, without accounting size of methods, called within this method. Thus, extracting pieces of code into independent methods could be useful sometimes, in the example with requireNonNull() this extraction is made for you already.
If you want evidence ... then the way to get it is to write a micro-benchmark.
(I recommend looking at the Calliper project first! Or JMH ... per Boris's recommendation. Either way, don't try and write a micro-benchmark from scratch. There are too many ways to get it wrong.)
However, you can tell your colleague two things:
The JIT compiler does a good job of inlining small method calls, and it is likely that this will happen in this case.
If it didn't inline the call, the chances are that the difference in performance would only be a 3 to 5 instructions, and it is highly unlikely that it would make a significant difference.
Yes, there is evidence that the difference between manual null check and Objects.requireNonNull() is negligible. OpenJDK commiter Aleksey Shipilev created benchmarking code that proves this while fixing JDK-8073479, here is his conclusion and performance numbers:
TL;DR: Fear not, my little friends, use Objects.requireNonNull.
Stop using these obfuscating Object.getClass() checks,
those rely on non-related intrinsic performance, potentially
not available everywhere.
Runs are done on i5-4210U, 1.7 GHz, Linux x86_64, JDK 8u40 EA.
The explanations are derived from studying the generated code
("-prof perfasm" is your friend here), the disassembly is skipped
for brevity.
Out of box, C2 compiled:
Benchmark Mode Cnt Score Error Units
NullChecks.branch avgt 25 0.588 ± 0.015 ns/op
NullChecks.objectGetClass avgt 25 0.594 ± 0.009 ns/op
NullChecks.objectsNonNull avgt 25 0.598 ± 0.014 ns/op
Object.getClass() is intrinsified.
Objects.requireNonNull is perfectly inlined.
where branch, objectGetClass and objectsNonNull are defined as follows:
#Benchmark
public void objectGetClass() {
o.getClass();
}
#Benchmark
public void objectsNonNull() {
Objects.requireNonNull(o);
}
#Benchmark
public void branch() {
if (o == null) {
throw new NullPointerException();
}
}
Your colleague is most likely wrong.
JVM is very intelligent and will most likely inline the Objects.requireNonNull(...) method. The performance is questionable but there will be definitely much more serious optimizations than this.
You should use the utility method from JDK.
Effective Java by Joshua Bloch
Item 67: Optimize judiciously
There are three aphorisms concerning optimization that everyone should know:
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason—including blind stupidity.
—William A. Wulf [Wulf72]
We should forget about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil.
—Donald E. Knuth [Knuth74]
We follow two rules in the matter of optimization:
Rule 1. Don’t do it.
Rule 2 (for experts only). Don’t do it yet—that is, not until you
have a perfectly clear and unoptimized solution.
—M. A. Jackson [Jackson75]
Meh, No. But, yes.
No, the direct code is always better since the method stack does not need to be touched.
Yes, if the VM implementation has null-check skips or some optimized null-checks.
Meh, method stack is so light to be modified and updated (yet it will consume some time).
As a general rule, readability and maintainability should trump optimization.
This rule safeguards against speculative optimization from people who think they know how a compiler works even though they have never even attempted to write one and they have never had a look inside one.
Your colleague is wrong unless they prove that the performance penalty is noticeable and untenable for users.
Objects.requireNonNull is more optimised as if you this you are code reusability.
Also in oracle requireNonNull si defined as
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
so its already in bytecode.
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.
I'm trying to reason about how the JIT of Hotspot reasons. I'm mostly interested in the latest compilation stage (C2 compiler). Does the JIT in Java rely on assertions for optimisations? If that was the case, I could imagine that there are examples where code could run faster with assertions enabled.
For example, in a piece of code like this:
static int getSumOfFirstThree(int[] array) {
assert(array.length >= 3);
return array[0] + array[1] + array[2];
}
Will the JIT, when assertions are enabled, be clever enough to eliminate the bounds checks on the array accesses?
Alternatively, are there other cases that you can think of (practical or not) where assertions will actually improve the native code that the JIT will compile?
In this case, there is multiple bounds checks to be made, and it is possible the JIT can coalesce them so that only one check is made, however the assertion doesn't avoid the need to make the check.
Assertions prevent optimisations like inlining as the method is larger and size is a factor in determining whether to inline a method. Typically inlining improves performance but in some cases it doesn't as it can cause the L0 or L1 CPU caches to become inefficient due to larger code being generated.
An example of where assertion can improve performance is something like this.
boolean assertionOn = false;
assert assertionOn = true;
if (assertionOn) {
assumeDataIsGood(); // due to checks elsewhere
} else {
expensiveCheckThatDataMightNotBeGood();
}
This is perhaps an anti-pattern to using assertions, but is going to be cheaper with assertions on by intent.
I know that in this code:
public static void main(String[] args) {myMethod();}
private Object myMethod() {
Object o = new Object();
return o;
}
the garbage collector will destroy o after the execution of myMethod because the return value of myMethod is not assigned, and therefore there are no references to it. But what if the code is something like:
public static void main(String[] args) {myMethod();}
private Object myMethod() {
int i = 5;
return i + 10;
}
Will the compiler even bother processing i + 10, seeing as the return value is not assigned?
And if i was not a simple primitive, but a larger object:
public static void main(String[] args) {myMethod();}
private Object myMethod() {
return new LargeObject();
}
where LargeObject has an expensive constructor, will the compiler still allocate memory and call the constructor, in case it has any side effects?
This would be especially important if the return expression is complex, but has no side effects, such as:
public static void main(String[] args) {
List<Integer> list = new LinkedList();
getMiddle();
}
private Object getMiddle(List list) {
return list.get((int) list(size) / 2);
}
Calling this method in real life without using the return value would be fairly pointless, but it's for the sake of example.
My question is: Given these examples (object constructor, operation on primitive, method call with no side effects), can the compiler skip the return statement of a method if it sees that the value won't be assigned to anything?
I know I could come up with many tests for these problems, but I don't know if I would trust them. My understanding of code optimization and GC are fairly basic, but I think I know enough to say that the treatment of specific bits of code aren't necessarily generalizable. This is why I'm asking.
First, lets deal with a misconception that is apparent in your question, and some of the comments.
In a HotSpot (Oracle or OpenJDK) Java platform, there are actually two compilers that have to be considered:
The javac compiler translates Java source code to bytecodes. It does minimal optimization. In fact the only significant optimizations that it does are evaluation of compile-time-constant expressions (which is actually necessary for certain comile-time checks) and re-writing of String concatenation sequences.
You can easily see what optimizations are done ... using javap ... but it is also misleading to because the heavy-duty optimization has not been done yet. Basically, the javap output is mostly unhelpful when it comes to optimization.
The JIT compiler does the heavy-weight optimization. It is invoked at runtime while your program is running.
It is not invoked immediately. Typically your bytecodes are interpreted for the first few times that any method is called. The JVM is gathering behavioral stats that will be used by the JIT compiler to optimize (!).
So, in your example, the main method is called once and myMethd is called once. The JIT compiler won't even run, so in fact the bytecodes will be interpreted. But that is cool. It would take orders of magnitude more time for the JIT compiler to optimize than you would save by running the optimizer.
But supposing the optimizer did run ...
The JIT code compiler generally has a couple strategies:
Within a method, it optimizes based on the information local to the method.
When a method is called, it looks to see if the called method can be inlined at the call site. After the inlining, the code can then be further optimized in its context.
So here's what is likely to happen.
Then your myMethod() is optimized as a free standing method, the unnecessary statements will not be optimized away. Because they won't be unnecessary in all possible contexts.
When / if a method call to myMethod() is inlined (e.g. into the main(...) method, the optimizer will then determine that (for example) these statements
int i = 5;
return i + 10;
are unnecessary in this context, and optimize it away.
But bear in mind that JIT compiler are evolving all of the time. So predicting exactly what optimizations will occur, and when, is next to impossible. And probably fruitless.
Advice:
It is worthwhile thinking about whether you are doing unnecessary calculations at the "gross" level. Choosing the correct algorithm or data structure is often critical.
At the fine grained level, it is generally not worth it. Let the JIT compiler deal with it.
UNLESS you have clear evidence that you need to optimize (i.e. a benchmark that is objectively too slow), and clear evidence there is a performance bottleneck at a particular point (e.g. profiling results).
Questions like "what will the compiler do?" about Java are a little naïve. First, there are two compilers and an interpreter involved. The static compiler does some simple optimization, like perhaps optimizing any arithmetic expression using effectively final operands. It certainly compiles constants, literals, and constant expressions into bytecode literals.The real magic happens at runtime.
I see no reason why result calculation would be optimized away except if the return value is ignored. Ignoring a return value is rare and should be rarer.
At runtime much more information is available in context. For optimizations the runtime interpreter plus compiler dynamic duo can account for things like "Is this section of code even worth optimizing?" HotSpot and its ilk won't optimize away the return new Foo(); instantiation if the caller uses the return value. But they will perhaps do it differently, maybe throw the attributes on the stack, or even in registers, circumstances permitting. So while the object exists on the logical Java heap, it could exist elsewhere on the physical JVM components.
Who knows if specific optimizations will happen? No one. But they or something like them, or something even more magical, might happen. Likely the optimizations that HotSpot performs are different from and better than what we expect or imagine, when in its wisdom it decides to take the trouble to optimize.
Oh, and at runtime HotSpot might deoptimize code it previously optimized. This is to maintain the semantics of the Java code.
I'm extending and improving a Java application which also does long running searches with a small DSL (in detail it is used for Model-Finding, yes it's in general NP-Complete).
During this search I want to show a small progress bar on the console. Because of the generic structure of the DSL I cannot calculate the overall search space size. Therefore I can only output the progress of the first "backtracking" statement.
Now the question:
I can use a flag for each backtracking statement to indicate that this statement should report the progress. When evaluating the statement I can check the flag with an if-statement:
public class EvalStatement {
boolean reportProgress;
public EvalStatement(boolean report) {
reportProgress = report;
}
public void evaluate() {
int progress = 0;
while(someCondition) {
// do something
// maybe call other statement (tree structure)
if (reportProgress) {
// This is only executed by the root node, i. e.,
// the condition is only true for about 30 times whereas
// it is false millions or billions of times
++progress;
reportProgress(progress);
}
}
}
}
I can also use two different classes:
A class which does nothing
A subclass that is doing the output
This would look like this:
public class EvalStatement {
private ProgressWriter out;
public EvalStatement(boolean report) {
if (report)
out = new ProgressWriterOut();
else
out = ProgressWriter.instance;
}
public void evaluate() {
while(someCondition) {
// do something
// maybe call other statement (tree structure)
out.reportProgress(progress);
}
}
}
public class ProgressWriter {
public static ProgressWriter instance = new ProgressWriter();
public void reportProgress(int progress) {}
}
public class ProgressWriterOut extends ProgressWriter {
int progress = 0;
public void reportProgress(int progress) {
// This is only executed by the root node, i. e.,
// the condition is only true for about 30 times whereas
// it is false millions or billions of times
++progress;
// Put progress anywhere, e. g.,
System.out.print('#');
}
}
An now really the question(s):
Is the Java lookup of the method to call faster then the if statement?
In addition, would an interface and two independet classes be faster?
I know Log4J recommends to put an if-statement around log-calls, but I think the main reason is the construction of the parameters, espacially strings. I have only primitive types.
EDIT:
I clarified the code a little bit (what is called often... the usage of the singleton is irrelevant here).
Further, I made two long-term runs of the search where the if-statement respectively the operation call was hit 1.840.306.311 times on a machine doing nothing else:
The if version took 10h 6min 13sek (50.343 "hits" per second)
The or version took 10h 9min 15sek (50.595 "hits" per second)
I would say, this does not give a real answer, because the 0,5% difference is in the measuring tolerance.
My conclusion: They more or less behave the same, but the overriding approach could be faster in the long-term as guessed by Kane in the answers.
I think this is the text book definition of over-optimization. You're not really even sure you have a performance problem. Unless you're making MILLIONS of calls across that section it won't even show up in your hotspot reports if you profiled it. If statements, and methods calls are on the order of nanoseconds to execute. So in order for a difference between them you are talking about saving 1-10ns at the most. For that to even be perceived by a human as being slow it needs to be in the order of 100 milliseconds, and that's if they user is even paying attention like actively clicking, etc. If they're watching a progress bar they aren't even going to notice it.
Say we wanted to see if that added even 1s extra time, and you found one of those could save 10 ns (it's probably like a savings of 1-4ns). So that would mean you'd need that section to be called 100,000,000 times in order to save 1s. And I can guarantee you if you have 100 Million calls being made you'll find 10 other areas that are more expensive than the choice of if or polymorphism there. Seems sorta silly to debate the merits of 10ns on the off chance you might save 1s doesn't it?
I'd be more concerned about your usage of a singleton than performance.
I wouldn't worry about this - the cost is very small, output to the screen or computation would be much slower.
The only way to really answer this question is to try both and profile the code under normal circumstances. There are lots of variables.
That said, if I had to guess, I would say the following:
In general, an if statement compiles down to less bytecode than a method call, but with a JIT compiler optimizing, your method call may get inlined, which is no bytecode. Also, with branch-prediction of the if-statement, the cost is minimal.
Again, in general, using the interfaces will be faster than testing if you should report every time the loop is run. Over the long run, the cost of loading two classes, testing once, and instantiating one, is going to be less than running a particular test eleventy bajillion times. Over the long term.
Again, the better way to do this would be to profile the code on real world examples both ways, maybe even report back your results. However, I have a hard time seeing this being the performance bottleneck for your application... your time is probably better spent optimizing elsewhere if speed is a concern.
Putting anything on the monitor is orders of magnitude slower than either choice. If you really got a performance problem there (which I doubt) you'd need to reduce the number of calls to print.
I would assume that method lookup is faster than evaluating if(). In fact, also the version with the if needs a method lookup.
And if you really want to squeeze out every bit of performance, use private final methods in your ProgessWriter's, as this can allow the JVM to inline the method so there would be no method lookup, and not even a method call in the machine code derived from the byte code after it is finally compiled.
But, probably, they are both rather close in performance. I would suggest to test/profile, and then concentrate on the real performance issues.
Which is faster in Java, and why?
try {
object.doSomething()
} catch (NullPointerException e) {
if (object == null) {
object = new .....;
object.doSomething();
} else throw e;
}
or
if (object == null) {
object = new .....;
}
object.doSomething();
and why?
The code would be called often, and object is only null the first time it's called, so don't take the cost of the thrown NPEinto account (it only happens once).
P.S. I know the second is better because of simplicity, readability, etc, and I'd surely go for that in real software. I know all about the evil of premature optimization, no need to mention it.
I'm merely curious about these little details.
You should absolutely use the latter way, not because it's faster, but because it's more idiomatic. Exceptions should not be used for control flow in your java programs.
this is purely anecdotal, but all the microbenchmarking I have ever done has shown that using exceptions for control flow won't be as performant as conditionals, although it's probably impossible to support this as a generalization and the JVM is very good at optimizing around things like this anyways, so YMMV.
Forget about speed - look at the size of the code in the first snippet versus the second.
Is the simpler option the best one? Easiest to read, takes up less space, etc. You should strive for code simplicity first, and then worry about speed once you've measured something as slow.
Besides, think about what the runtime needs to do in order to determine that it needs to throw a NullPointerException - it has to check if the current reference is null. So even without measuring, it would logically make sense that performing the check yourself is simpler, rather than leaving it up to the JRE to make the check and create a NullPointerException and unwind the stack.
Regardless of speed, the first way is not good programming practice. For example, what if object was not null but object.doSomething() resulted in the NullPointerException?
This is one reason why you should not use exceptions to control program flow!
To answer your question, version 1 is much slower when it explodes because creating Exceptions is quite expensive, but it is not faster than version 2 because the JVM must do the null check itself anyway so you're not saving anytime. The compiler is likely to optimize the code so it's no faster anyway.
Also Exceptions should be reserved for the exceptional. Initial state of null is not exceptional.
Use the lazy initialization pattern:
SomeClass getIt() {
if (it == null)
it = new SomeClass();
return it;
}
...
getIt().someMethod();
Check the The Java Specialists' Newsletter - Issue 187 Cost of Causing Exceptions for some interesting internal details.
a thrown exception (first example) is nearly always slower than normal control flow code (second example)
that aside the second is much cleaner and easier to understand
I'm going to say the second solution is faster. Not because I'm an expert on the JIT or VM but because it makes sense that a single branch-if-equal assembly-level routine is faster than looking up the object in memory, determining that it is null (the same test, I assume), throwing an exception and possibly mucking up the stack.