Consider the following method:
private static long maskAndNegate(long l) {
int numberOfLeadingZeros = Long.numberOfLeadingZeros(l)
long mask = CustomBitSet.masks[numberOfLeadingZeros];
long result = (~l) & mask;
return result;
}
The method can be abbreviated to:
private static long maskAndNegate(long l) {
return (~l) & CustomBitSet.masks[Long.numberOfLeadingZeros(l)];
}
Are these two representations equal in actual run time? In other words, does the Java compiler optimize away the unnecessary definition of extra variables, that I've placed for readability and debugging?
The Java compiler itself hardly does any optimization. It's the JIT that does almost everything.
Local variables themselves are somewhat irrelevant to optimization though - a multi-operator expression still needs the various operands logically to go on the stack, just in unnamed "slots". You may well find that the generated bytecode for your two implementations if very similar, just without the names in the second case.
More importantly, any performance benefit that might occur very occasionally from reducing the number of local variables you use is almost certainly going to be insignificant. The readability benefit of the first method is much more likely to be significant. As always, avoid micro-optimizing without first having evidence that the place you're trying to optimize is a bottleneck, and then only allow optimizations which have proved their worth.
(By the time you've proved you need to optimize a particular method, you'll already have the tools to test any potential optimization, so you won't need to guess.)
The code is not significantly large enough to be optimized for starters. And in the second way you are just saving the memory used for storing references to numberOfLeadingZeros and all.
But when you will use this code significantly enough on runtime such as 10000 times at least, then JIT will identify it as HOT code and then optimize it with neat tricks such as Method Inlining and similar sorts.
But in your case preferable option is first one as it is more readable.
You should not compromise Readability for small optimizations.
Related
If for some reason I have to use as little memory space as possible, then is the second code bellow better that the first? (the code is just for illustration and doesn't have any meaning). (edit: imagine I want to make the assembly code of this before any optimization done by the JVM. Then do i use 99999998 extra memory locations in the first procedure compared to the second one? the focus is just one memory usage)
First:
for(int i=0; i<99999999; i++){
int k=2*i
}
Second:
int k=0;
for(int i=0; i<99999999; i++){
k=2*i
}
What I'm sure of :
In every case, The difference will not be visible. if you want to make such small optimization, Java is surely not the best technology. Which makes me recommend the first one cause it make the code more readable and logical. (Find it strange to declare a variable outside the for if you use it only inside it, it's confusing).
What I think :
In your small example and since your looking for a memory footprint. The first one is better because it follow the implicit rule mentioned in this comment: the smaller the scope is the better it is.
In the first case the variable k is used only in a really small loop. So the optimizer will easily understand it and use only a register, so no memory usage and less instructions.
In the second case, it will be harder for the optimizer to determine that k is not use elsewhere. So it could allow some memory instead of using a register. It will then use some memory and be less optimized since it will need instructions to load and store the memory.
As mentionned in this comment, it will mostly depend on how you use it. In your example the optimizer will detect it's the same usage in both case and will use no memory. But in harder code it will not always find it. So I recommend to have the smaller scope has possible.
#pranay-khandelwal 's response links to an excellent discussion of this question in a different language. The Java JVM, however, throws bytecode around at runtime to try to achieve better performance, which can complicate things.
There's actually another discussion here on a similar topic of in/out best practices in general for readability, which resulted in some benchmarks and discussion that one of the participants documented here
As a general rule of thumb the second option will be better for memory and performance under almost all circumstances - where the former may be more self-documenting and maintainable, and avoid accidental use elsewhere in the outer scope.
Since you mention that the code in your post is only a representative example and this could apply to more than just simple types:
Replacing the contents of an already registered memory area is less costly than registering a new one and deregistering the old one (or waiting for it to be garbage collected). Even where a language's compiler or interpreter smartly uses recently unreferenced things to store new things, that work also takes work, and is overhead that can optimistically be avoided with outer declarations - though as others mention, this is usually an unnecessary and potentially bug-spawning micro-optimization.
As from these short examples you provided, the second option. However, it always depends on the logic of your code.
Thinking about performance and minimising execution space and time, the second code scales better even though it looks countering some good coding practices.
K in your code is used only inside the loop block. However, it is "reused" over multiple "block iterations". Take a look at the syntax of your for loop, it declares i (int i) in the beginning of the statement; this declaration will happen just once. Again, declaring the variable multiple times may lead to waste to time and memory.
The JVM optimiser might do a good job in general, simple cases. However, it might fail in capturing the semantics of your code (Java).
for(int i=0,k=0; i<99999999; i++){
k=2*i
}
double calcTaxAmount() {
double price = getA() * getB() + getC();
double taxRate = getD() + getE();
return price * taxRate;
}
The function above calculates the amount of tax payment.
The price and the rate are calculated by calling some other functions.
I introduced two local variables price and taxRate to just improve code readability, so both will be used only once.
Will those kinds of "one-time" local variables be substituted and inlined at compile time with most modern compilers?
Obviously, it depends on the compiler. Quite a few compilers are actually brain-dead when it comes to optimization, because they are dealing with dynamic languages which are complex enough that most optimizations are invalid and many others are only safe if very restrictive conditions are met (for instance, any function call could have nearly any effect). For instance, all Python implementations feature a compiler, but most of them only do very few peephole optimizations, which may not be sufficient to eliminate all overhead.
That said, if you're talking about statically typed languages (which your example hints at), then usually yes. Liveness analysis can detect the equivalence (you still need a storage location for, but the lifetime is the same), and any reasonably register allocator can avoid spilling the values needlessly.
That said, this is a really bad focus for optimization. If you actually want to make stuff faster, look at the final code and profile with realistic scenarios. And if you're going to micro-optimize, apply some common sense. Even assuming this function is a hotspot, the actual computation and getting the values may easily take 100x more time. A non-inlined function call takes pretty long compared to a stack store, and a cache miss is also pretty cost at this level.
Generally yes.
Java only optimises code to native code after it has been called many time (10,000 time by default) If the method is not calls very much it won't make much difference in any case.
Even if it makes a difference of say 1 ns each, you would need to call this method 1 billion times to add a delay of 2 seconds. If its only 10 million times you are unlikely to notice the difference.
As long as the compiler can prove that they aren't aliased and modified externally, the compiler should be able to optimize them away (and I suspect that it can determine that here).
If you make them const I can't think of a compiler that couldn't optimize that.
All that said, this sounds like premature optimization and I wouldn't change the code even if it's fractionally slower because it adds to clarity.
Depends entirely on the compiler for C. Presumably yes for current compilers with proper optimization options turned on.
For Java it will not be optimized by the compiler (javac), but it may get optimized by the JIT when the code actually executes.
That beeing said, those local variables add very little overhead anyway. If the compiler decides to optimize the expressions to the equivalent of:
return (getA() * getB() + getC()) * (getD() + getE());
It will still require some form of temporary storage (stack or register) to store the intermediate results of the subexpressions. So it shouldn't make much of a difference anyway.
I wouldn't worry about it and go with what offers better readability.
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.
This question has received a total of several paragraphs of answer. Here is the only sentence that actually tells me what I was looking for:
Your examples would make little difference since intermediate computations need to be stored temporarily on the stack so they can be used later on.
In fact, it answers my question perfectly and completely =)
Unlike all the cruft telling me "nooo don't ask that question". >_<
Like if you have a method, and you change it by increasing the number of local variables but make no other changes, does it make the method slower? Here's an example:
void makeWindow() {
Display
.getContext()
.windowBuilder()
.setSize(800, 600)
.setBalloonAnimal(BalloonAnimal.ELDER_GOD.withColor(PUCE))
.build();
}
or
void makeWindow() {
DisplayContext dc = Display.getContext();
WindowBuilder wb = db.windowBuilder();
BalloonAnimal god = BalloonAnimal.ELDER_GOD;
BalloonAnimal puceGod = god.withColor(PUCE);
wb.setSize(800, 600).setBalloonAnimal(puceGod).build();
}
Another example:
int beAnExample(int quiche) {
return areGlobalsEvil?
quiche * TAU/5:
highway(quiche, Globals.frenchFrenchRevolution);
}
or
int beAnExample(int quiche) {
if (areGlobalsEvil) {
int to5 = TAU/5;
int result = quiche * to5;
return result;
} else {
Game french = Globals.frenchFrenchRevolution;
int result = highway(quiche, french);
return result;
}
}
Really, what I'm asking is: Is the number of this sort of local variable even relevant by the time the method's compiled to bytecode? If so, what about once Hotspot gets to work on it?
This question is relevant to the code generator I'm working on.
The easy answer is no. Local variables consume runtime stack space. Allocating space for them only marginally increases the number of instructions. Your examples would make little difference since intermediate computations need to be stored temporarily on the stack so they can be used later on. Focus more on the readability of your programs rather than needless micro-optimizations.
If you're interested in looking at the actual bytecode of a class, investigate the javap program.
Don't worry about it. The compiler can do all sorts of crazy, make-your-head-asplode optimizations. Start with code that's correct and maintainable. Programmer time is worth far more than processor tiem.
Test it by running each method 1,000,000 times and divide the total time to calculate the cost per execution. In all likelihood, it won't be noticable.
Actually, Java compilers may even be smart enough to just compile it out.
Write your code for readability to reduce long term cost of maintenance. Then tune it in the 5% of places where you really need to.
The chances are that it will make little (if any) difference, and the "little" will be insignificant.
Focus on making your generator correct and maintainable, and let the Java compiler (particularly the JIT compiler) do the micro-optimization of the generated code.
Note that #Edawg's advice on looking at the bytecode is not necessarily helpful. The JIT compiler aggressively optimizes the native code that it generates from the bytecodes. It can be difficult to predict which of two bytecode sequences is going to be faster. Certainly, counting bytecodes, method calls and so on can be misleading.
The only way to be sure that you are generating "optimal" Java source code would be to compile it and benchmark it on your target platform. Even then, there's a good chance that your efforts at source-code level optimization will be negated ... by JIT compiler changes.
This is not a hotspot issue. There may need to be additional byte codes to load and store the local variables, but let the compiler worry about optimizing that.
You should concentrate on issues like null pointer checking in your generated code and how to report errors in a meaningful way that is tied to the source input that you are code generating from.
if i have the code
int getA(){
return a;
}
and then do something like
int b = obj.getA();
instead of
int b = obj.a;
will that mean that the stack will have to be pushed and popped ultimately slowing down my code?
The JIT compiler will inline the method.
The code should look like
int b = obj.GetA();
I have two answers for you:
I don't think that there is a significant performance penalty for using the getter vs accessing the variable directly. I would worry more about how understandable and readable the code is than performance for this sort of decision.
According to OO design principles, which may or may not be important to you, you would normally hide the data and provide the getter method to access it—there is a detailed discussion on the merits of this approach here.
Theoretically there is some runtime penalty, due to a method call being made. In reality, this has very little effect on the overall performance due to two reasons:
Unless the obj.getA() is taking place inside the inner-most loop of your program, then its effect on the overall performance of your code will be negligible. When performance is an issue you should consider the bottleneck of your code. There's no point in optimizing code that is out not at these hot spots. In order to identify these spots you need to analyze the execution of your code via a profiler.
As #Michael was saying the JVM uses a "Just In Time" compiler/optimizer that inlines code based on actual execution. It performs just this kind of optimizations (see this talk)