From: Arne Vajhøj on
rossum wrote:
> A question for the Java gurus. When coding in C or C++ I use
> 'register' to hint to the compiler that something might usefully be
> kept in a place with easy/quick access:

Good C code style in the 1980's.

:-)

Don't do it today.

It is a deal - the compiler does not give you hints about how
to write code - you do not give the compiler hints about how
to compile.


> In Java there is no direct equivalent of 'register', the closest
> probably is 'final' to indicate that the local variable will not
> change. The approximate Java equivalent is:
>
> for (int i = 0; i < 20; ++i) {
> final int iSquared = i * i;
> for (int j = 0; j < 250; ++j) {
> // Calculations involving i, iSquared and j
> }
> }
>
> However, in Java the compiler is creating byte code and the machine
> code is created by the JIT from the bytecode so there is a less direct
> connection between my source and the machine code.
>
> At last, my question: does the hint given by the 'final' keyword on a
> local variable get through to the JIT or is it just wasted typing?
>
> Some days I add a 'final' to my unchanging local variables, other days
> I can't be bothered. Which is the better practice? Is there likely
> to be any impact on execution speed?

The final keyword on local variable will not improve
performance (in general).

But some people use it anyway to ensure that the variable
is not changed.

I think it can be good for fields, but that it is misplaced
for arguments and local variables because:
- it clutters the code
- if it is a problem to look at the entire method and see
whether the variable is changed or not, then the method
is too long and should be broken up

http://www.ibm.com/developerworks/java/library/j-jtp1029.html

talks a little bit about some of it (including the register
keyword !).

Arne
From: Kevin McMurtrie on
Keyword 'final' doesn't make the code faster but it can make code easier
to read for humans because there's no need to check for updates.

Getting HotSpot to optimize best is hit and miss because it's so opaque.
Good practices like manual CSE can perform better or worse than
automatic CSE. Float might be faster or slower than int. It depends on
factors that aren't visible from the source code. It's one of several
factors that make Java an unpleasant language for signal and graphics
processing.

--
I will not see your reply if you use Google.
From: Dave Searles on
markspace wrote:
> rossum wrote:
>>
>> I am talking about local variables, not member variables.
>
> I was just re-reading in Java Concurrency in Practice that some
> modifiers are important, because the JIT/javac will hoist variables out
> of loops:
>
> volatile boolean done = false;
>
> while(!done)
> processData();
>
> "done" will be hoist out of the loop with out the volatile modifier,
> resulting in an infinite loop.

Since that loop cannot set "done" the loop is infinite anyway (barring
an uncaught exception or System.exit() call beneath processData()
somewhere).
From: Dave Searles on
Arne Vajh�j wrote:
> It is a deal - the compiler does not give you hints about how
> to write code

Sure it does; they're called "warnings".

> - you do not give the compiler hints about how
> to compile.
From: Tronje Krop on
rossum wrote:
> On Tue, 15 Sep 2009 13:03:02 +0100, rossum <rossum48(a)coldmail.com>
> wrote:
>
>> A question for the Java gurus. When coding in C or C++ I use
>> 'register' to hint to the compiler that something might usefully be
>> kept in a place with easy/quick access:
>>
>> for (int i = 0; i < 20; ++i) {
>> register int iSquared = i * i;
>> for (int j = 0; j < 250; ++j) {
>> // Calculations involving i, iSquared and j
>> }
>> }
>>
>> That makes sense because the compiler is directly writing machine code
>> and can make use of the hint if it wants to.
>>
>> In Java there is no direct equivalent of 'register', the closest
>> probably is 'final' to indicate that the local variable will not
>> change. The approximate Java equivalent is:
>>
>> for (int i = 0; i < 20; ++i) {
>> final int iSquared = i * i;
>> for (int j = 0; j < 250; ++j) {
>> // Calculations involving i, iSquared and j
>> }
>> }
>>
>> However, in Java the compiler is creating byte code and the machine
>> code is created by the JIT from the bytecode so there is a less direct
>> connection between my source and the machine code.
>>
>> At last, my question: does the hint given by the 'final' keyword on a
>> local variable get through to the JIT or is it just wasted typing?
>>
>> Some days I add a 'final' to my unchanging local variables, other days
>> I can't be bothered. Which is the better practice? Is there likely
>> to be any impact on execution speed?
>>
>> I am talking about local variables, not member variables.
>>
>> Thanks,
>>
>> rossum
> Rather than respond to everyone individually, I will reply here.
>
> As I suspected, final has no real effect on bytecode or machine code
> though it is useful as a flag to other programmers and the javac
> compiler.
>
> Thank you all for your input.

Hi, I'm not that sure about the effect of final on local variables.
I have made a simple check using eclipse and the bytecode outline
plugin. As I expected the following code does make a difference:

public void test() {
int y = 0;
final int x = 5;
for (int i = 0; i < x; i++) {
y += i * x;
}
}

It translates to the following bytecode:

// access flags 1
public test() : void
L0
LINENUMBER 15 L0
ICONST_0
ISTORE 1
L1
LINENUMBER 16 L1
ICONST_5
ISTORE 2
L2
LINENUMBER 17 L2
ICONST_0
ISTORE 3
L3
GOTO L4
L5
LINENUMBER 18 L5
FRAME APPEND [int int int]
ILOAD 1: y
ILOAD 3: i
ICONST_5
IMUL
IADD
ISTORE 1: y
L6
LINENUMBER 17 L6
IINC 3: i 1
L4
FRAME SAME
ILOAD 3: i
ICONST_5
IF_ICMPLT L5
L7
LINENUMBER 20 L7
RETURN
L8
LOCALVARIABLE this Test L0 L8 0
LOCALVARIABLE y int L1 L8 1
LOCALVARIABLE x int L2 L8 2
LOCALVARIABLE i int L3 L7 3
MAXSTACK = 3
MAXLOCALS = 4

You can see that in lines guarded by lables 4 and 5 the constant 5
(ICONST_5) is loaded on the stack instead of the variable x from
slot 2 (ILOAD 2). Effectively, the compiler would have eliminated
the variable x completely without debugging mode, as shown below:

// access flags 1
public test() : void
ICONST_0
ISTORE 1
ICONST_0
ISTORE 2
GOTO L0
L1
FRAME APPEND [int int]
ILOAD 1
ILOAD 2
ICONST_5
IMUL
IADD
ISTORE 1
IINC 2 1
L0
FRAME SAME
ILOAD 2
ICONST_5
IF_ICMPLT L1
RETURN
MAXSTACK = 3
MAXLOCALS = 3


You see, "final" does make a difference under certain circum-
stances. But it is not clear, whether this will result in per-
formance differences as the HotSpot-Compiler will draw its
own conclusions, but this is very likely (as the code size is
smaller).

By the way without "final" on x the bytecode would have looked
as follows:

// access flags 1
public test() : void
ICONST_0
ISTORE 1
ICONST_5
ISTORE 2
ICONST_0
ISTORE 3
GOTO L0
L1
FRAME APPEND [int int int]
ILOAD 1
ILOAD 3
ILOAD 2
IMUL
IADD
ISTORE 1
IINC 3 1
L0
FRAME SAME
ILOAD 3
ILOAD 2
IF_ICMPLT L1
RETURN
MAXSTACK = 3
MAXLOCALS = 4

Best regards

Tronje
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8
Prev: inheriting a main method
Next: Adding int to a float