Reputation: 3764
I have to use a variable which will never be changed in method which will be frequently used in many threads. Which of these variants are more efficient?
Variant 1:
public class Test {
private static int myVar;
public Test(int myVar){
this.myVar=myVar;
}
public void frequentlyUsedMultiThreadMethod(){
//read myVar
}
}
Variant 2:
public class Test {
public void frequentlyUsedMultiThreadMethod(int myVar){
//read myVar
}
}
Variant 3:
public class Test {
private final int myVar;
public Test(int myVar){
this.myVar=myVar;
}
public void frequentlyUsedMultiThreadMethod(){
//read myVar
}
}
Upvotes: 5
Views: 1315
Reputation: 3913
What about this solution, uses less memory, no instances created. you need some business in a method. Data will be stored in the thread stack and reduce the thread context switching which consumes additional time if you reuse threads like ThreadPoolExecutor . If myVar can be changed for another use cases it is better to add it as argument to the method.
public class Test {
public static void frequentlyUsedMultiThreadMethod(int myVar){
//read myVar
}
}
Upvotes: 0
Reputation: 533750
The simplest, clearest and least error prone solution is also the fastest (or fast enough) which is often the case in Java.
Before you worry about speed, you should ask yourself; what is the simplest, clearest and least error prone approach? Passing values via static values is very error prone, esp when you have a multi-threaded application. Don't do it. The speed is unimportant if your program doesn't work.
However, in this case it is also confusing to use static
fields. It is not clear to the caller what they must set first. If you use recursion, this will make your job even harder.
To make matters worse, local variables can be optimised more than static fields. This means static fields are also slower, possibly much slower.
Note: to prevent JIT optimisations JMH uses a "blackhole" for the resulting value to stop code being optimised away, it uses a static
field to do it.
Option 3 is perhaps best provided the value never changes, esp if you have multiple values, however if the value does change it will be slower as you are adding overhead to create the Test
object each time, the JIT might not optimise away.
Upvotes: 4
Reputation: 726929
Reading a single int
, no matter from what location, is so extremely fast, that you would be hard-pressed to construct a piece of code that demonstrates a meaningful difference in time between the three approaches from your question, let alone finding a difference in arbitrary piece of code. The problem in constructing a benchmark is that the variable never changes, so the compiler would be allowed to read it once per method call, even if frequentlyUsedMultiThreadMethod
accesses it in a loop.
When this is the case, the best approach is to think what approach reflects the logical use of the data in your program.
myVar
are used for different instances.myVar
is one per instance, and that it does not change. This is the most logical approach to the situation that you described in the question.Upvotes: 8
Reputation: 140573
Probably variant 2 might be slightly better, as things can be pulled of the stack there.
But: you should very much more worry on creating a good (aka SOLID ) design, instead of worrying about such subtleties.
It is very hard to understand what the JVM and the just-in-time compiler will do to your input in the very first place.
Meaning: you focus on creating good designs; you avoid outright stupid errors; and that is good enough regarding "performance thinking". Anything else is premature optimization.
In other words: you only have performance issues ... if you notice them. And then, you don't guess what is better; you start profiling your specific application, to understand where the real bottlenecks are at runtime.
Of course, your question is interesting in the "what happens at runtime"; but it is really "not relevant" in guiding your design/implementation decisions. Those need to be driven by a will to create helpful abstractions, and a "model" that really fits your domain. Because those are the things that really matter!
Then you end up with code that other people can understand; and more importantly: that can be changed later on, when you figure what your real problems are!
Upvotes: 1