I have code that all over the place(probably 20-30 instances) does this:
<widget>.setVisible((condition == VIEW) || (condition == EDIT));
Logically I do understand that the Java compiler should and probably will optimize this to calculate it up front and simply use the calculated boolean.
My question is is there any way to actually verify that this is the case?
CLARIFICATION
condition is a private class member with no way to modify it past construction.
Disassemble the class file with javap, e.g.
javap -c com.example.ClassName
to see the bytecode source. But why not just guarantee the optimization by extracting into a temp boolean variable?
is there any way to actually verify that this is the case?
You could try to verify this by looking at the bytecode disassembly, then at the machine code produced by HotSpot, etc.
However, I think this strategy is fraught with difficultly. It is also fragile, since the result depends on the compiler/JVM and on the exact nature of condition (is it local? a class member? final? volatile?)
If you care about the optimization for performance reasons [1], my advice would be to perform it manually, by factoring out the common expression.
[1] I assume that you've profiled the code, and know for a fact that this is a bottleneck.
Disassemble the byte code.
That said, these kinds of optimizations may be done at run time, may depend on the declaration of condition, depend on where the conditions are located, and so on. Tracking down optimizations such as this is non-trivial in all but the simplest use cases.
Related
I have been pulled into a performance investigation of a code that is similar to the below:
private void someMethod(String id) {
boolean isHidden = someList.contains(id);
boolean isDisabled = this.checkIfDisabled(id);
if (isHidden && isDisabled) {
// Do something here
}
}
When I started investigating it, I was hoping that the compiled version would look like this:
private void someMethod(String id) {
if (someList.contains(id) && this.checkIfDisabled(id)) {
// Do something here
}
}
However, to my surprise, the compiled version looks exactly like the first one, with the local variables, which causes the method in isDisabled to always be called, and that's where the performance problem is in.
My solution was to inline it myself, so the method now short circuits at isHidden, but it left me wondering: Why isn't the Java Compiler smart enough in this case to inline these calls for me? Does it really need to have the local variables in place?
Thank you :)
First: the java compiler (javac) does almost no optimizations, that job is almost entirely done by the JVM itself at runtime.
Second: optimizations like that can only be done when there is no observable difference in behaviour of the optimized code vs. the un-optimized code.
Since we don't know (and the compiler presumably also doesn't know) if checkIfDisabled has any observable side-effects, it has to assume that it might. Therefore even when the return value of that method is known to not be needed, the call to the method can't be optimized away.
There is, however an option for this kind of optimization to be done at runtime: If the body (or bodies, due to polymorphism) of the checkIfDisabled method is simple enough then it's quite possible that the runtime can actually optimize away that code, if it recognizes that the calls never have a side-effect (but I don't know if any JVM actually does this specific kind of optimization).
But that optimization is only possible at a point where there is definite information about what checkIfDisabled does. And due to the dynamic class-loading nature of Java that basically means it's almost never during compile time.
Generally speaking, while some minor optimizations could possibly be done during compile time, the range of possible optimizations is much larger at runtime (due to the much increased amount of information about the code available), so the Java designers decided to put basically all optimization effort into the runtime part of the system.
The most-obvious solution to this problem is simply to rewrite the code something like this:
if (someList.contains(id)) {
if (this.checkIfDisabled(id)) {
// do something here
If, in your human estimation of the problem, one test is likely to mean that the other test does not need to be performed at all, then simply "write it that way."
Java compiler optimizations are tricky. Most optimizations are done at runtime by the JIT compiler. There are several levels of optimizations, the maximum number of optimizations by default will be made after 5000 method invocations. But it is rather problematic to see which optimizations are applied, since JIT compile the code directly into the platform's native code
Take the following code snap for example:
public int demoMethod(){
SomeClass object= getItFromSomewhere();
return object.getResult();
}
also we can directly return getItFromSomewhere().getResult(). My question is whether the definition of "object" will low down the performance? And in some case, maybe the temporary local variable is very complicated, such as
SomeClass object = otherClassObject.getMethod1().getMethod2().getMethod3().getMethod4();
return object.getMethod5();
If I don't use the temporary "object", the statement will be very difficult to read, how about you guys deal with this case?
Afaik will be completely removed by jit. So there should not be any impact on performance introducing additional local variables to simplify expressions.
PS: The long expression, a.d.b.c is called a 'train wreck' by uncle bob. They are hard to read and a PITA to debug when you get an exception like a NPE.
As a general rule (in my opinion, but I trust I am not alone), your code should be optimized for readability before any other kind of optimization. This will allow other programmers to improve it later on, if needed. A very fast but unreadable code quickly becomes useless as nobody is able to make changes to it. Also, trust the compilers (javac and the JIT): they know how to rewrite your code to remove unused statements, like a variable that is not actually necessary.
Then, if speed is an issue, you should try to improve it by choosing more appropriate data structures (especially containers) and algorithms.
Lastly, if speed is still an issue (very rare nowadays), you should seek the advice of a specialist. There are people who do wonders with code that is seemingly efficient to begin with, but this is not something the average developer should do on a daily basis.
Is there any difference between:
String x = getString();
doSomething(x);
vs.
doSomething(getString());
Resources and performance wise, Especially is it's done within a loop for tens, hundreds or thousands of times?
It has the same overhead. Local variables are just there to make your life easier. At the VM level they don't necessarily exist and certainly not anymore when machine code is run.
So what you need to worry about here is getString(), whether it is potentially expensive. x has very likely no effect at all.
Let me first begin by saying that your overriding goal should almost always be to maintain code readability. Your compiler is almost always better at trivial optimizations than you are. Trust it!
In response to your specific example: the bytecode generated for each example IS different. It didn't appear to make much difference though, because there wasn't a statistically significant or even consistent difference between the two approaches in a loop over Integer.MAX_VALUE iterations.
I believe both would be the same at compile time, the first may become more code readable in some cases though.
Both the statements are same. only difference is that in first approach you have used a local variable X which can be avoided using second syntax.
That largely depends on the use-case. Are you going to make repeated calls to doSomething using that exact String? Then using the local variable is a bit more efficient. However, if it's a single call or multiple calls with different Strings, it makes no difference.
I was curious, I see this kind of thing a lot:
Arrays.sort(array, new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
return Math.abs(a) < Math.abs(b);
}
});
since the anonymous class created here has no instance variables, is the standard JDK compiler smart enough to only instantiate that anonymous class once and reuse it? Or is it advisable to instantiate that anonymous class in a static field and always pass the static Comparator object?
UPDATE: When I say "JDK compiler", I mean the JIT portion too. The above is also just an example. I was really curious if I should, as a best practice, create static fields for the above instead of inlining anonymous class instantiations. In some cases the performance/resource usage issue will be negligible. But other cases might not be...
javac will definitely not do such thing; that would violate the language semantics. JVM could optimize it in theory, but it's not that smart yet. A static one would be faster.
Ironically, such analysis and optimization would be easy for javac, and it can be done today, except it's forbidden to do so - the source says new, so javac must new.
Rumor has it that the coming lambda expression in java 8 will make an effort on this issue, in
Arrays.sort(array, (Integer a,Integer b) => Math.abs(a)<Math.abs(b) )
javac is required to analyze that the lambda is stateless, and a lazily created single instance is enough, and that's what it must compile the code into.
The answer is maybe.
javac will compile this into bytecode that is true to your code. Therefore, the class will be instantiate anew each time this code is called. However the JVM performs many sophisticated optimisations at runtime, and MIGHT - depending on many factors - perform some optimisations here.
In any case, unless you've noticed a real performance issue here, I'd recommend not trying to manually optimise.
You can use javap to check yourself; my suspicion is that it will create it on every call. Such optimizations are handled by hotspot but in this case since the anonymous only has methods (no fields to initialize) the overhead is very small.
The real question here is not what javac will do. As Steve McLeod says, javac will produce bytecode which matches your source code. The question is what hotspot will do at runtime. I imagine it will simple inline the whole lot (including the Math.abs() call).
The compiler does very little optimisation. The jit does most of it. It will optimise this code but it won't avoid creating Integer objects and unless you have an array of Integer this will be your bottle neck. So much so that any other optimisation it does won't matter.
Does Java have something similar to a branch or jump table?
A branch or jump table table is, according to wikipedia,
a term used to describe an efficient method of transferring program control (branching) to another part of a program (or a different program that may have been dynamically loaded) using a table of branch instructions.
Does Java have something like this or do I just have to use if/else if/else or case statements?
Java has a switch statement, but whether it compiles to a jump table in bytecode is implementation-dependent. In general, compilers will build you a jump table if they find nice constants for each case in your switch statement. I'm not sure you should really care how it's implemented, though. If you're coding in Java in the first place, you're probably just fine letting the compiler and the JIT take care of these things for you.
Note that switch only works with integer primitive types and enums, so you do need to use if/else statements if you're using other object types (and you probably shouldn't be comparing doubles or floats for equality anyway).
Finally, even though enum references are technically "constant", some compilers will only generate you a jump table when you switch on enums if your switch statement is in the same compilation unit where the enum is defined. Otherwise, it will generate you an if/else chain (as you'd have to do for regular objects). For the nitty gritty details, see the java.net forums on extending switch usage for Objects.
Does Java have something like this or do I just have to use if/else if/else or case statements?
I think case statements ( with the switch in java ) is the equivalent.
Additionally in OOP the switch could be coded once and then let polymorphism to the job.
From : http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html
It depends on your requirements.
a term used to describe an efficient method of transferring program control (branching) to another part of a program (or a different program that may have been dynamically loaded) using a table of branch instructions."
One way to transfer program control is to call a function. One way to call the right function when you have several to choose from, is to key it off of the type of an object. That's called polymorphism. Java and other Object Oriented languages have polymorphism, implemented through inheritance (subclassing). Not sure how it's implemented in Java, but in C++ there's (generally? or always?) a pointer in each object that points to the v-table for it's class, which contains pointers to virtual functions.
I seriously doubt the lack of a user-defined jump table is going to cripple the performance of your java application.
Yes, absolutely.
If you code a switch statement, then depending on various things the switch is converted into a tableswitch instruction in bytecode. Generally
The switch must depend on an int value
The highest int value and the lowest int value must not be too far apart
The simplest way to acheive this is to use java enums, which are handled specially by the compiler. The relevant documentation is in the Java Virtual Machine Specification. Of course, the JIT compiler almost certainly converts these directly into very fast switches in the machine code of whatever platform you are running on.
Having said that, the real answer to your question is "this is the sort of thing that you worry about when you are doing machine code, not programming in a high-level language".
I don't believe that you need those sort of performance hacks in Java. I would concentrate first of writing readable code and using decent algorithms - these will deliver more performance benefits than what you're discussing.
In most standalone applications, the vast majority of time is spent sitting around waiting for the user to do something. In most web applications, the amount of time running bytecode in the JVM should be swamped by network time, database time or business logic.
If you're really worried about the performance of part of your Java app, you can move it into JNI code and bypass the Java interpreter altogether.
I think that is how some switch statements are implemented "under the hood" so to speak.
Other than that, you could do something similar with something like HashMap<whatever, Method>, where you use map.get(something).invoke(). But that kinda defeats the purpose because it wouldn't be as fast as a jump table, and I can't think of a good case where OOP programming/polymorphism wouldn't do the job better and cleaner.
THe kind of branch/jump tables you're talking about are not directly provided by high level languages such as Java, C, etc., but are generated by compilers in machine code or byte code. In other words, your compiler may use them but you don't see them.
You can use enum to do this.
// doesn't work in c#
enum Switch implements Runnable {
OPTION1() {
public void run() {
// do something.
}
},
OPTION2() {
public void run() {
// do something.
}
},
OPTION3() {
public void run() {
// do something.
}
}
}
Switch option = Switch.valueOf(switchOptionTest);
option .run();
//or
Switch[] options = Switch.values();
Switch option = options[nSwitchOption];
option .run();
You could do this with reflection and a generic HashMap that stored anonymous inner classes but it would be a horrible hack.
It is really elegant to do in C# due to native anonymous methods, but not in java.