Efficiency of Java code with primitive types?

I would prefer the first over the second because it keeps the loop variables out of the way of the rest of the code in the method. Since they're not visible outside of the loop, you can't accidentally refer to them later on.

I would prefer the first over the second because it keeps the loop variables out of the way of the rest of the code in the method. Since they're not visible outside of the loop, you can't accidentally refer to them later on. The other answers are right, too: don't worry about this sort of thing for performance.

But do think about it for code readability reasons, and for communicating programmer intent to the next person who comes along. This is much more important than micro-optimization concerns. Now, that's at the Java language (as in Java Language Specification) level.At the Java Virtual Machine level, it makes absolutely no difference which of those two you use.

The locals are allocated in exactly the same way. If you're not sure, you can always compile it and see what happens. Let's make two classes, f1 and f2, for the two versions: $ cat f1.

Java public class f1 { void f() { for(int I = 0 ; I f1decomp $ javap -c f2 > f2decomp And compare them: $ diff f1decomp f2decomp 1,3c1,3 Compiled from "f2. Java" > public class f2 extends java.lang. Object{ > public f2(); There's absolutely no difference in the bytecode.

1 for the decompilation demonstration. – tylermac May 7 '10 at 14:32 that's a Booyaah, in your face teacher! Answer, right there.

:P – st0le Dec 30 '10 at 6:34.

IT. DOESN'T. MAKE.A.DIFFERENCE.

Stop micro-optimizing. These little tricks don't make programs run much faster. Concentrate on big picture optimizations and writing readable code.

Declare variables where they make sense, and where it helps understanding the semantics of the overall code in the bigger context, not because you think it's faster one place over another.

1 Agreed! Your focus should be why you're doing a nested loop and what operations are taking place INSIDE the nested loop. Not the two wimpy ints on the outside!

– basszero May 7 '10 at 10:47 Still, the question remains very interesting. Why isn't Java compiler optimizing away both loops because they have no side effects? Even if // some operations was more than a comment, it's an easy micro-optimization for javac so both variants should be equally fast.

– Alexandru May 7 '10 at 11:24 1 @Alexandru: . Java to bytecode is unoptimized. The most effective optimization happens at JIT level, not at javac level.

– polygenelubricants May 7 '10 at 12:09 1 I agree with the sentiment of not micro-optimizing but there is one thing that matters here: variable scope. That can create real problems. – cletus May 7 '10 at 12:14 1 @Alexandru debuging, fast compiling, plattform dependent optimisations, usage based optimisation are some reasons.

– josefx May 7 '10 at 14:06.

Beware the perils of micro-benchmarking! I took the code, wrapped a method around the outside, and ran that 10 times in a loop. Results: 50, 3, 3, 0, 0, 0, 0, 0, .... Without some actual code in the loops, the compilers are able to figure out that the loops do no useful work and optimize them away completely.

Given the measured performance, I suspect that this optimization might have been done by javac. Lesson 1: Compilers will often optimize away code that does useless "work". The smarter the compiler is, the more likely it is that this sort of thing will happen.

If you don't allow for this in the way you code it, a benchmark can be meaningless. So I then added the following simple calculation in both loops if (i But now we see the effects of JVM warmups in (in this case) the first two pairs of loop iterations. The first two pairs of iterations (one method call) are probably run purely in interpreted mode.

And it looks the third iteration might actually be running in parallel with the JIT.By the third pair of iterations, we are most likely running pure native code. And from then on, the difference between the timing of the two versions of loop is simply noise. Lesson 2: always take into account the effect of JVM warmup.

This can seriously distort benchmark results, both micro and macro. Conclusion - once the JVM has warmed up, there is no measurable difference between the two versions of the loop.

3 +1 for good explanation, example of the effects of the in process optimization of the JVM/JIT. My own thought, people often seem to forget that the compiled code does not have to be the written code verbatim if it is computationally equivalent, i.e. The classic example of recursive fibonnaci translated to a simple loop by a smart compiler (before it even gets to the JVM/JIT).

– M. Jessup May 7 '10 at 11:37 I'm pretty sure that the compiler (javac) is NOT responsible for the optimization of the first results (zero times). That's done by the JVM: I only got zeros if running with the -server option, normal times (about 10 s) otherwise.

Inspecting the byte code does not show any optimization (despite reusing the same address for the local variables for both loops, no matter where they were declared) – Carlos Heuberger May 10 '10 at 9:25.

The second is worse. Why? Because the loop variable is scoped outside the loop.

I and j will have a value after the loop is done. Generally that isn't what you want. The first scopes the loop variables so it's only visible within the loop.

It compiles fine for me. – Marcelo Cantos May 7 '10 at 10:23 Agreed - any gain in efficiency is not worth possible issue because of reuse of I and j. However, funny enough, in C++ not all compilers enforce the scope of I and j if declared in loop – David Relihan May 7 '10 at 10:26 @Marcelo - @cletus never said anything about compilation errors.

– Stephen C May 7 '10 at 10:27 Stephen, he did in the first version. I don't know why it doesn't appear as an edit, but I saw it. The remark was that the second version doesn't even compile.

– Marcelo Cantos May 7 '10 at 10:30 Has it been edited? Both codes work fine in my eclipse... Edit: ok, ok – Random May 7 '10 at 10:31.

I would guess that there is absolutely no difference in efficiency for any half-decent JVM implementation.

No, It does not make a difference at all (speed wise). They both get compiled into the same code. And there's no allocation and deallocation going on like MasterGaurav said.

When the method starts, the JVM allocates enough memory slots for all local variables, and no more allocations occurs until the end of the method. The only small tiny insignificant difference (other than the scope), is that with the first example, the memory allocated for I & j can be reused for other variables. Therefore, the JVM will allocates fewer memory slots for this method (well, yous saved some bits).

First off, yes your teacher is wrong, the second code is not better. What does better mean anyway? This is because in any normal loop the operations inside the loop body are the part, that are time consuming.So Code 2 is just a micro optimization, which doesn't add enough speed (if any) to justify the bad readability of the code.

Second is better for speed. Reason is that in the first case, the scope of j is limited to the inner for loop. As such, the moment, the inner loop is completed, the memory for j is de-allocated, and again allocated for the next iteration of the outer loop.

Because the memory allocation and deallocation take some time, even though it's on stack, the performance of the first one is slower.

2 There is no such thing as stack "allocation". The code simply opts to use a certain portion of available stack for the purpose of storing the int. – Marcelo Cantos May 7 '10 at 10:27 Yes, the answer is wrong.

There's no allocation and deallocation going on in the JVM – H-H May 7 '10 at 10:36 The variable j goes out scope in the first case... so, what does it mean? I agree there's nothing as stack allocation... but then, using the value on the stack and making it out of scope... is it only a compile-time stuff? – MasterGaurav May 7 '10 at 10:46 MasterGaurav, I explained that in my answer.

The JVM allocates once enough memory for all local variables. When a local variable goes out of scope, the same memory slot is used for another local variable – H-H May 7 '10 at 11:21 Thanks HH! My understanding mistake :) – MasterGaurav May 7 '10 at 12:44.

There is one more aspect, which is very important about the two different versions: While in variant 2 there are only two temporary objects created (i and j), variant 1 will create 100000 objects (1 x I and 999999 x j). Probably your compiler is going to optimize this, but this is something you can´t be sure of. If it doesn´t optimize it, the garbage collection will behave significantly worse.

Int" is not an object type. – Thorbjørn Ravn Andersen May 7 '10 at 12:03.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions