Reputation: 7863
Given these code samples:
Sample 1
public class SomeClass {
private static final int onlyUsedByMethodFoo = 1;
// many lines of code
public static void foo() {
final String value = items[onlyUsedByMethodFoo];
}
}
Sample 2
public class SomeClass {
// many lines of code
public static void foo() {
final int onlyUsedByMethodFoo = 1;
final String value = items[onlyUsedByMethodFoo];
}
}
I prefer the second code sample because the value is close to where it is used. It is only used by Foo() anyway. I don't see an advantage declaring it as a global value, even though Foo() is called frequently. The only advantage to a global static value I can see is potentially in performance, but it is unclear how much of a performance advantage it would be. Perhaps Java recognizes this and optimizes the byte-code.
Concerning performance, is it worth declaring a constant value globally? Does the performance gain justify moving a constant value farther from where it is used and read by the programmer?
Upvotes: 4
Views: 337
Reputation: 1569
The JIT compiler of specific Java implementations / versions may choose to optimize specially based on various things it can deduce about the code. However, in general, it is able to optimize a static final
class member easier than a final
method variable.
The fact that the variable in question is a primitive (an int
) may change things; if it were a reference type, it'd be a lot harder for it to optimize. Since it's not an Object, there are no tricks you can do with reference equality or anything like that; consider this example and compare it against your final int
:
void foo() {
final Object o = new SomeObject();
}
I think, in this case, the final
doesn't help performance at all, because the expectation of the semantics would be that if you are comparing the o
between individual method invocations, it should be a different object, i.e. it won't ==
the o
from a previous method invocation. But if you make it a static final class member, you truly have a singleton object.
It's not clear to me if JIT would necessarily have to optimize or not optimize final
primitives in methods, because it could conceivably optimize it out into only having it being stored in one place, but it is clear that for reference types, the class member is going to be (marginally) lower overhead in terms of memory/CPU.
Upvotes: 0
Reputation: 803
It's not a good practice to do pre-mature optimization. Concentrate on the design, a good design is easy to extend and maintain. If you have a good design & code, identifying performance issues (if any) will not be cumbersome and can be dealt with. Again - never do pre mature optimization. Also, nowadays,compilers are tuned to generate optimized byte codes.
Upvotes: 0
Reputation: 4197
Java compiler substitutes all occurrences of this static final field by it's value; local variables are part of runtime stack frame. See The Java® Virtual Machine Specification for more comprehensive explanation.
I don't think that in your case there is any difference in performance.
Upvotes: 5
Reputation: 106498
First, this kind of micro-optimization isn't really a detail you should concern yourself with. If anything, there are more copious wins in performance in much more involved pieces of your code.
This sort of micro-optimization doesn't net you much, and you may sacrifice readability for a negligible performance boost.
Your code has no places in which there's a huge performance bottleneck, so I wouldn't expect any major performance wins if you made any micro-optimizations.
To your main question, the idea behind the static final variable would be twofold:
I would argue that, if other classes aren't making use of it, then it doesn't need to be public
. I would still recommend it be a class variable, so it'd have the style of Sample 1, but with the declaration private static final int onlyUsedByMethodFoo = 1;
.
Upvotes: 2
Reputation: 20707
For such cases the performance (for primitive types at least) is not an issue. What's more important is, is the "code quality", i.e. how consistent, readable and clean your code is. So, if you want to have a context-specific variable, define it where it really belongs to, and don't mess the global context up
Upvotes: 0