4

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?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
TERACytE
  • 7,553
  • 13
  • 75
  • 111
  • Why would it be a performance gain to have to go look up a value from memory instead of having a literal right in the method body in the byte code? – Affe Jan 29 '14 at 19:43
  • [This question](http://stackoverflow.com/q/306862/1679863) might be of interest to you. – Rohit Jain Jan 29 '14 at 19:45

5 Answers5

5

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.

Filipp Voronov
  • 4,077
  • 5
  • 25
  • 32
  • 1
    Wow! So much passion around this question! Thank-you everyone for your responses. This question resulted from a conversation I had with a coworker where s/he was trying to convince me that the global static variable was easier to maintain and better performance than a local one. After reading the responses & performing some local testing, I think its better IMHO to keep a variable close to where it is used. There does not appear to be a significant performance hit, its easier to find, and remains in context with the code. Thanks everyone. I appreciate your time. – TERACytE Jan 31 '14 at 16:23
2

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:

  • You avoid magic numbers, thus making your intent clear.
  • Should your value need to change, you can change it in one place as opposed to several places.

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;.

Makoto
  • 104,088
  • 27
  • 192
  • 230
0

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

injecteer
  • 20,038
  • 4
  • 45
  • 89
0

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.

user1339772
  • 783
  • 5
  • 19
0

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.

allquixotic
  • 1,481
  • 2
  • 18
  • 37