What I'm asking is whether there is a difference between doing this:
public Something importantBlMethod(SomethingElse arg) {
if (convenienceCheckMethod(arg)) {
// do important BL stuff
}
}
private boolean convenienceCheckMethod(SomethingElse arg) {
// validate something
}
And this:
public Something importantBlMethod(SomethingElse arg) {
if (convenienceCheckMethod(arg)) {
// do important BL stuff
}
}
private static boolean convenienceCheckMethod(SomethingElse arg) {
// validate something
}
I actually use option 1 as it seems more natural to me.
So is there a style/convention/performance difference between the first and the second way ?
Thanks,
As suggested in the comments I tested it, in my benchmarks the dynamic method is faster.
This is the test code:
public class Tests {
private final static int ITERATIONS = 100000;
public static void main(String[] args) {
final long start = new Date().getTime();
final Service service = new Service();
for (int i = 0; i < ITERATIONS; i++) {
service.doImportantBlStuff(new SomeDto());
}
final long end = new Date().getTime();
System.out.println("diff: " + (end - start) + " millis");
}
}
This is the service code:
public class Service {
public void doImportantBlStuff(SomeDto dto) {
if (checkStuffStatic(dto)) {
}
// if (checkStuff(dto)) {
// }
}
private boolean checkStuff(SomeDto dto) {
System.out.println("dynamic");
return true;
}
private static boolean checkStuffStatic(SomeDto dto) {
System.out.println("static");
return true;
}
}
For 100000 iterations the dynamic method passes for 577ms, the static 615ms.
This however is inconclusive for me since I don't know what and when the compiler decides to optimize.
This is what I'm trying to find out.
Performance wise: The difference, if any, is negligible.
The rule of thumb is to declare your method static if it doesn't interact with any members of its class.
If the result of the function does not depend on anything but the arguments, it should be static. If it depends on an instance, make it an instance member.
It's not about performance; it's about semantics. Unless you're calling this function a million times a second, you will not notice a performance difference, and even then the difference won't be significant.
It all depends on the context. Generally static methods/variables are declared in a class so that an external class can make use of them.
If you are making a call to a local method then you should generally use instance methods rather than making static calls.
FYI, your syntax for calling the static method from an instance method is wrong. You have to supply the class name.
If your method requires instance data or calls to other instance methods, it must be an instance method.
If the function only depends on its arguments, and no other static data, then it might as well be an instance method too - you'll avoid the need to repeat the class name when you invoke the static function.
IMHO, there's no particular need to make the function static unless:
it's callable from other classes (i.e. not private), and
it doesn't refer to instance variables, and
it refers to other static class data
It might, it might not. It might be different between different executions of your code.
Here's the only thing that you can know without digging into the Hotsport code (or the code of your non-Hotspot JVM):
The static method is invoked with invokestatic, which does not require an object reference.
The instance private method is invoked with invokespecial, which does require an object reference.
Both of those opcodes have a process for resolving the actual method to invoke, and those processes are relatively similar (you can read the specs). Without counting the instructions of an actual implementation, it would be impossible to say which is faster.
The invokespecial pushes an extra value onto the stack. The time to do this is counted in fractions of a nanosecond.
And making all of this moot, Hotspot has a wide range of optimizations that it can perform. It probably doesn't have to do the actual method resolution more than once during your program's run. It might choose to inline the method (or it might not), but that cost would again be roughly equivalent.
According to me NO binding of static method is same as non-static private i.e early binding.
.
Compiler actually adds code of method (static or non-static private) to your code while creating it's byte code.
Update : Just came through this article. It says instance methods binding is dynamic so if method is not non-static private then. Your static method is faster.
I checked, I hope it does what you wanted to know, the code won't be beautiful:
public class main {
#SuppressWarnings("all")
public static void main(String[] args) {
main ma = new main();
int count = Integer.MAX_VALUE;
long beg = (new Date()).getTime();
for (int i = 0; i < count; i++) {
ma.doNothing();
}
System.out.println("priv : " + new Long((new Date()).getTime() - beg).toString());
beg = (new Date()).getTime();
for (int i = 0; i < count; i++) {
doNothingStatic();
}
System.out.println("privstat : " + new Long((new Date()).getTime() - beg).toString());
}
private void doNothing() {
int i = 0;
}
private static void doNothingStatic() {
int i = 0;
}
}
results:
priv : 1774
privstat : 1736
priv : 1906
privstat : 1783
priv : 1963
privstat : 1751
priv : 1782
privstat : 1929
priv : 1876
privstat : 1867
It doesn't look like dependent on static - nonstatic private method. I am sure the differences are coming from the current burden of the machine.
I take part in coding competitions and I have observed, that non-static methods are faster(however minimal) than the static methods. Of course, it depends on your use and the what the situation demands, but the static methods gives poorer performance as compared to non-static ones. By convention, you can use static methods for the ease of code, but creating an instance of the class and calling the method will give better performance.
Related
For some background, I'm currently on chapter 8 in my book, we finished talking about arraylists, arrays, if statements, loops etc. Now this part of the book talks about call by reference,value and some other pretty neat things that seem odd to me at first.I've read What situation to use static and some other SO questions, and learned quite a bit as well.
Consider the following example my book gave (among many examples)
There is another reason why static methods are sometimes necessary. If
a method manipulates a class that you do not own, you cannot add it to
that class. Consider a method that computes the area of a rectangle.
The Rectangle class in the standard library has no such feature, and
we cannot modify that class. A static method solves this problem:
public class Geometry
{
public static double area(Rectangle rect)
{
return rect.getWidth() * rect.getHeight();
}
// More geometry methods can be added here.
}
Now we can tell you why the main method is static. When the program
starts, there aren’t any objects. Therefore, the first method in the
program must be a static method.
Ok, thats pretty cool, up until now I've just been really blindly putting public in front of all my methods, so this is great to know. But the review small problem on the next page caught my attention
The following method computes the average of an array list of numbers:
public static double average(ArrayList<Double> values)
Why must it be a static method?
Here I was like wait a sec. I'm pretty sure I did this without using static before. So I tried doing this again and pretty easily came up with the following
import java.util.ArrayList;
class ArrList
{
private double sum;
public ArrList()
{
sum = 0;
}
public double average(ArrayList <Double> values)
{
for(int i = 0; i < values.size() ; i++)
{
sum+=values.get(i);
}
return sum / values.size();
}
}
public class Average
{
public static void main(String [] args)
{
ArrList arrListObj = new ArrList();
ArrayList<Double> testArrList = new ArrayList<Double>();
testArrList.add(10.0);
testArrList.add(50.0);
testArrList.add(20.0);
testArrList.add(20.0);
System.out.println(arrListObj.average(testArrList));
}
}
TLDR
Why does my book say that public static double average(ArrayList<Double> values) needs to be static?
ATTEMPT AT USING STATIC
public class Average
{
public static void main(String [] args)
{
ArrayList<Double> testArrList = new ArrayList<Double>();
ArrayList<Double> testArrListTwo = new ArrayList<Double>();
testArrList.add(10.0);
testArrList.add(50.0);
testArrList.add(20.0);
testArrList.add(20.0);
testArrListTwo.add(20.0);
testArrListTwo.add(20.0);
testArrListTwo.add(20.0);
System.out.println(ArrList.average(testArrList));
System.out.println(ArrList.average(testArrListTwo)); // we don't get 20, we get 53.3333!
}
}
It doesn't.
The only method which needs to be static is the initial main() method. Anything and everything else is up to you as the programmer to decide what makes sense in your design.
static has nothing to do with public accessors (as you allude to), and it has nothing to do with the technical operation being performed. It has everything to do with the semantics of the operation and the class which holds it.
An instance (non-static) method exists on a particular instance of a class. Semantically it should perform operations related to that specific instance. A static method exists on a class in general and is more conceptual. It doesn't do anything to a particular instance (unless it's provided an instance of something as a method argument of course).
So you really just need to ask yourself about the semantics of the operation. Should you need new instance of an object to perform an operation? Or should the operation be available without an instance? That depends on the operation, on what the objects represent, etc.
If it is not static, then any other class that wants to use this method must first create an instance of this object.
From some other class:
Average.average(new ArrayList<Double>()); // legal only if static
new Average().average(new ArrayList<Double>()); // necessary if not static
// and only makes sense if Average can be instantiated in the first place
It's legal to make it an instance (i.e. not static) variable, but the method is actually harder to understand. If it is static then whoever reads the code knows it does not use any member variables of the class.
// In the class body
int x = 0; // member variable
public static double average() {
x = x + 1; // illegal
}
The less something can do, the easier to understand what it does do.
Static methods like the area, average are usually utility functions. You don't need any object to use an utility function. For example consider Math.pow you don't need to instantiate any object to use the power function, just use Math.pow(10.0, 2.0) to get (10.0)^2
In short :
Static method means class method, that is no instance of that object is needed to invoke.
whereas your average method is an instance method, you need an object to invoke that method.
I haven't been coding anything for a while now and I decided to practice a bit. I came up with this issue at the very beginning of my program and I spent last night trying to figure out or find a way around this problem but I didn't get any expected results.
First, let's see the class:
public class Task {
private static int priority;
private static int taskTime;
private static boolean solved;
public void setPriority(int p){this.priority = p;}
public void setTasktime(int t){this.taskTime = t;}
public void setSolved(boolean s){solved = s;}
public int getPriority(){return this.priority;}
public int getTaskTime(){return this.taskTime;}
public boolean getSolved(){return this.solved;}
public Task(int p, int t){
this.priority = p;
this.taskTime = t;
this.solved = false;
}
public static class ComparePriority implements Comparator<Task>{
#Override
public int compare(Task t1, Task t2){
return Integer.compare(t1.getPriority(), t2.getPriority());
}
}
}
Now, this is the piece of code I am trying to run:
public class main {
public static void main(String[] args) {
Task t1 = new Task(20,1);
Task t2 = new Task(13,2);
Task t3 = new Task(10,5);
ArrayList<Task> t = new ArrayList<Task>();
t.add(t2);
t.add(t3);
t.add(t1);
System.out.println("List size: " + t.size());
System.out.println("T1 object's priority: " + t1.getPriority());
System.out.println("T2 object's priority: " + t2.getPriority());
System.out.println("T3 object's priority: " + t3.getPriority());
for(int i=0;i<t.size();i++){
System.out.println("Current object task time: "+ t.get(i).getTaskTime());
System.out.println("Current index:" + i);
}
Collections.sort(t, new Task.ComparePriority());
for(int i=0;i<t.size();i++){
System.out.println("Current object task time (post sort): " + t.get(i).getTaskTime());
System.out.println("Current index: " + i);
}
}
I understand that these attributes were defined in a static way and I should be accessing them as Class.method();
If I were to instantiate 3 objects (as used as example up above), is there any way to access them statically but still get every piece of information read from the object to be unique instead of "the same"?
Also why is accessing them non-statically discouraged?
You are asking for contradicting things.
access them statically
contradicts
still get every piece of information read from the object to be unique instead of "the same"
If you wish the former, you should expect the same value to be seen by all instances.
If you wish the latter, don't define them as static.
As for accessing them non-statically, as far as I know it makes no difference. They only reason I'd avoid accessing static members non-statically (i.e. by dereferencing an object of that class) is readability. When you read object.member, you expect member to be a non-static member. When you read ClassName.member you know it's a static member.
When a static method is called, it deals with everything on the class-level, rather than the object-level. This means that the method has no notion of the state of the object that called it - it will be treated the same as for every object that calls it. This is why the compiler gives a warning. It is misleading to use a static method with the form a.Method() because it implies that the method is invoked on the object, when in the case of static methods, it is not. That's why it's bad practice to call a static method on an instance of an object.
I think you misunderstand the difference between class variable and static variable. Program has only one value for static variable mean while every object has it own value for a class variable. It is also considered misleading to use this with static members.
Accessing them non-statically is not discouraged at all in programming, but actually encouraged. If you want to access things non-statically, try putting that code in another class in a method. Then in this class put
public static void main(String[] args) {
AnotherClass ac = new AnotherClass();
ac.initializeProcess()
}
I don't know why people like downgrading questions, I guess they think they were never new at all.
Update:
Static objects don't get thrown in the garbage-collector too quickly but it is saved as long there are references to it; static objects can cause memory issues
https://stackoverflow.com/a/572550/1165790
I want to use this feature in Java because the function that I'm designing is called rarely (but when it is called, it starts a recursive chain) and, therefore, I do not want to make the variable an instance field to waste memory each time the class is instantiated.
I also do not want to create an additional parameter, as I do not want to burden external calls to the function with implementation details.
I tried the static keyword, but Java says it's an illegal modifier. Is there a direct alternative? If not, what workaround is recommended?
I want it to have function scope, not class scope.
I want it to have function scope, not class scope.
Then you are out of luck. Java provides static (class scoped), instance and local variables. There is no Java equivalent to C's function-scoped static variables.
If the variable really needs to be static, then your only choice is to make it class scoped. That's all you've got.
On the other hand, if this is a working variable used in some recursive method call, then making it static is going to mean that your algorithm is not reentrant. For instance, if you try to run it on multiple threads it will fall apart because the threads will all try to use the same static ... and interfere with each other. In my opinion, the correct solution would be either to pass this state using a method parameter. (You could also use a so-called "thread local" variable, but they have some significant down-sides ... if you are worrying about overheads that are of the order of 200 bytes of storage!)
How are you going to keep a value between calls without "wasting memory"? And the memory consumed would be negligible.
If you need to store state, store state: Just use a static field.
Caution is advised when using static variables in multi-threaded applications: Make sure that you synchronise access to the static field, to cater for the method being called simultaneously from different threads. The simplest way is to add the synchronized keyword to a static method and have that method as the only code that uses the field. Given the method would be called infrequently, this approach would be perfectly acceptable.
Static variables are class level variables. If you define it outside of the method, it will behave exactly as you want it to.
See the documentation:
Understanding instance and Class Members
The code from that answer in Java...
public class MyClass {
static int sa = 10;
public static void foo() {
int a = 10;
a += 5;
sa += 5;
System.out.println("a = " + a + " sa = " + sa);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
foo();
}
}
}
Output:
$ java MyClass
a = 15 sa = 15
a = 15 sa = 20
a = 15 sa = 25
a = 15 sa = 30
a = 15 sa = 35
a = 15 sa = 40
a = 15 sa = 45
a = 15 sa = 50
a = 15 sa = 55
a = 15 sa = 60
sa Only exists once in memory, all the instances of the class have access to it.
Probably you got your problem solved, but here is a little more details on static in Java. There can be static class, function or variable.
class myLoader{
static int x;
void foo(){
// do stuff
}
}
versus
class myLoader{
static void foo(){
int x;
// do stuff
}
}
In the first case, it is acting as a class variable. You do not have to "waste memory" this way. You can access it through myLoader.x
However, in the second case, the method itself is static and hence this itself belongs to the class. One cannot use any non-static members within this method.
Singleton design pattern would use a static keyword for instantiating the class only once.
In case you are using multi-threaded programming, be sure to not generate a race condition if your static variable is being accessed concurrently.
I agree with Bohemian it is unlikely memory will be an issue. Also, duplicate question: How do I create a static local variable in Java?
In response to your concern about adding an additional parameter to the method and exposing implementation details, would like to add that there is a way to achieve this without exposing the additional parameter. Add a separate private function, and have the public function encapsulate the recursive signature. I've seen this several times in functional languages, but it's certainly an option in Java as well.
You can do:
public int getResult(int parameter){
return recursiveImplementation(parameter, <initialState>)
}
private int recursiveImplementation(int parameter, State state){
//implement recursive logic
}
Though that probably won't deal with your concern about memory, since I don't think the java compiler considers tail-recursive optimizations.
The variables set up on the stack in the recursive call will be function (frame) local:
public class foo {
public void visiblefunc(int a, String b) {
set up other things;
return internalFunc(a, b, other things you don't want to expose);
}
private void internalFunc(int a, String b, other things you don't want to expose) {
int x; // a different instance in each call to internalFunc()
String bar; // a different instance in each call to internalFunc()
if(condition) {
internalFunc(a, b, other things);
}
}
}
Sometimes state can be preserved by simply passing it around. If required only internally for recursions, delegate to a private method that has the additional state parameter:
public void f() { // public API is clean
fIntern(0); // delegate to private method
}
private void fIntern(int state) {
...
// here, you can preserve state between
// recursive calls by passing it as argument
fIntern(state);
...
}
How about a small function-like class?
static final class FunctionClass {
private int state1; // whichever state(s) you want.
public void call() {
// do_works...
// modify state
}
public int getState1() {
return state1;
}
}
// usage:
FunctionClass functionObject = new FunctionClass();
functionObject.call(); // call1
int state1AfterCall1 = functionObject.getState1();
functionObject.call(); // call2
int state1AfterCall2 = functionObject.getState1();
I have a class with several methods. Now I would like to define a helper method that should be only visible to method A, like good old "sub-functions" .
public class MyClass {
public methodA() {
int visibleVariable=10;
int result;
//here somehow declare the helperMethod which can access the visibleVariable and just
//adds the passed in parameter
result = helperMethod(1);
result = helperMethod(2);
}
}
The helperMethod is only used by MethodA and should access MethodA's declared variables - avoiding passing in explicitly many parameters which are already declared within methodA.
Is that possible?
EDIT:
The helper mehod is just used to avoid repeating some 20 lines of code which differ in only 1 place. And this 1 place could easily be parameterized while all the other variables in methodA remain unchanged in these 2 cases
Well you could declare a local class and put the method in there:
public class Test {
public static void main(String[] args) {
final int x = 10;
class Local {
int addToX(int value) {
return x + value;
}
}
Local local = new Local();
int result1 = local.addToX(1);
int result2 = local.addToX(2);
System.out.println(result1);
System.out.println(result2);
}
}
But that would be a very unusual code. Usually this suggests that you need to take a step back and look at your design again. Do you actually have a different type that you should be creating?
(If another type (or interface) already provided the right signature, you could use an anonymous inner class instead. That wouldn't be much better...)
Given the variables you declare at the top of your method can be marked as final (meaning they don't change after being initialized) You can define your helper method inside a helper class like below. All the variables at the top could be passed via the constructor.
public class HelperClass() {
private final int value1;
private final int value2;
public HelperClass(int value1, int value2) {
this.value1 = value1;
this.value2 = value2;
}
public int helperMethod(int valuex) {
int result = -1;
// do calculation
return result;
}
}
you can create an instance of HelperClass and use it inside the method
It is not possible. It is also not good design. Violating the rules of variable scope is a sure-fire way to make your code buggy, unreadable and unreliable. If you really have so many related variables, consider putting them into their own class and giving a method to that class.
If what you mean is more akin to a lambda expression, then no, this is not possible in Java at this time (but hopefully in Java 8).
No, it is not possible.
I would advise you create a private method in your class that does the work. As you are author of the code, you are in control of which other methods access the private method. Moreover, private methods will not be accessible from the outside.
In my experience, methods should not declare a load of variables. If they do, there is a good chance that your design is flawed. Think about constants and if you couldn't declare some of those as private final variables in your class. Alternatively, thinking OO, you could be missing an object to carry those variables and offer you some functionality related to the processing of those variables.
methodA() is not a method, it's missing a return type.
You can't access variables declared in a method from another method directly.
You either has to pass them as arguments or declare methodA in its own class together with the helpermethods.
This is probably the best way to do it:
public class MyClass {
public void methodA() {
int visibleVariable=10;
int result;
result = helperMethod(1, visibleVariable);
result = helperMethod(2, visibleVariable);
}
public int helperMethod(int index, int visibleVariable) {
// do something with visibleVariable
return 0;
}
}
Is there any performance benefit one way or another? Is it compiler/VM specific? I am using Hotspot.
First: you shouldn't be making the choice of static vs non-static on the basis of performance.
Second: in practice, it won't make any difference. Hotspot may choose to optimize in ways that make static calls faster for one method, non-static calls faster for another.
Third: much of the mythos surrounding static versus non-static are based either on very old JVMs (which did not do anywhere near the optimization that Hotspot does), or some remembered trivia about C++ (in which a dynamic call uses one more memory access than a static call).
Four years later...
Okay, in the hope of settling this question once and forever, I have written a benchmark which shows how the different kinds of calls (virtual, non-virtual, static) compare to each other.
I ran it on ideone, and this is what I got:
(Larger number of iterations is better.)
Success time: 3.12 memory: 320576 signal:0
Name | Iterations
VirtualTest | 128009996
NonVirtualTest | 301765679
StaticTest | 352298601
Done.
As expected, virtual method calls are the slowest, non-virtual method calls are faster, and static method calls are even faster.
What I did not expect was the differences to be so pronounced: Virtual method calls were measured to run at less than half the speed of non-virtual method calls, which in turn were measured to run a whole 15% slower than static calls. That's what these measurements show; the actual differences must in fact be slightly more pronounced, since for each virtual, nonvirtual, and static method call, my benchmarking code has an additional constant overhead of incrementing one integer variable, checking a boolean variable, and looping if not true.
I suppose the results will vary from CPU to CPU, and from JVM to JVM, so give it a try and see what you get:
import java.io.*;
class StaticVsInstanceBenchmark
{
public static void main( String[] args ) throws Exception
{
StaticVsInstanceBenchmark program = new StaticVsInstanceBenchmark();
program.run();
}
static final int DURATION = 1000;
public void run() throws Exception
{
doBenchmark( new VirtualTest( new ClassWithVirtualMethod() ),
new NonVirtualTest( new ClassWithNonVirtualMethod() ),
new StaticTest() );
}
void doBenchmark( Test... tests ) throws Exception
{
System.out.println( " Name | Iterations" );
doBenchmark2( devNull, 1, tests ); //warmup
doBenchmark2( System.out, DURATION, tests );
System.out.println( "Done." );
}
void doBenchmark2( PrintStream printStream, int duration, Test[] tests ) throws Exception
{
for( Test test : tests )
{
long iterations = runTest( duration, test );
printStream.printf( "%15s | %10d\n", test.getClass().getSimpleName(), iterations );
}
}
long runTest( int duration, Test test ) throws Exception
{
test.terminate = false;
test.count = 0;
Thread thread = new Thread( test );
thread.start();
Thread.sleep( duration );
test.terminate = true;
thread.join();
return test.count;
}
static abstract class Test implements Runnable
{
boolean terminate = false;
long count = 0;
}
static class ClassWithStaticStuff
{
static int staticDummy;
static void staticMethod() { staticDummy++; }
}
static class StaticTest extends Test
{
#Override
public void run()
{
for( count = 0; !terminate; count++ )
{
ClassWithStaticStuff.staticMethod();
}
}
}
static class ClassWithVirtualMethod implements Runnable
{
int instanceDummy;
#Override public void run() { instanceDummy++; }
}
static class VirtualTest extends Test
{
final Runnable runnable;
VirtualTest( Runnable runnable )
{
this.runnable = runnable;
}
#Override
public void run()
{
for( count = 0; !terminate; count++ )
{
runnable.run();
}
}
}
static class ClassWithNonVirtualMethod
{
int instanceDummy;
final void nonVirtualMethod() { instanceDummy++; }
}
static class NonVirtualTest extends Test
{
final ClassWithNonVirtualMethod objectWithNonVirtualMethod;
NonVirtualTest( ClassWithNonVirtualMethod objectWithNonVirtualMethod )
{
this.objectWithNonVirtualMethod = objectWithNonVirtualMethod;
}
#Override
public void run()
{
for( count = 0; !terminate; count++ )
{
objectWithNonVirtualMethod.nonVirtualMethod();
}
}
}
static final PrintStream devNull = new PrintStream( new OutputStream()
{
public void write(int b) {}
} );
}
It is worth noting that this performance difference is only applicable to code which does nothing other than invoking parameterless methods. Whatever other code you have between the invocations will dilute the differences, and this includes parameter passing. Actually, the 15% difference between static and nonvirtual calls is probably explained in full by the fact that the this pointer does not have to be passed to the static method. So, it would only take a fairly small amount of code doing trivial stuff in between calls for the difference between different kinds of calls to be diluted to the point of having no net impact whatsoever.
Also, virtual method calls exist for a reason; they do have a purpose to serve, and they are implemented using the most efficient means provided by the underlying hardware. (The CPU instruction set.) If, in your desire to eliminate them by replacing them with nonvirtual or static calls, you end up having to add as much as an iota of extra code to emulate their functionality, then your resulting net overhead is bound to be not less, but more. Quite possibly, much, much, unfathomably much, more.
Well, static calls can't be overridden (so are always candidates for inlining), and don't require any nullity checks. HotSpot does a bunch of cool optimizations for instance methods which may well negate these advantages, but they're possible reasons why a static call may be faster.
However, that shouldn't affect your design - code in the most readable, natural way - and only worry about this sort of micro-optimization if you have just cause (which you almost never will).
It is compiler/VM specific.
In theory, a static call can be made
slightly more efficient because it
doesn't need to do a virtual function
lookup, and it can also avoid the
overhead of the hidden "this"
parameter.
In practice, many compilers will
optimize this out anyway.
Hence it's probably not worth bothering about unless you have identified this as a truly critical performance issue in your application. Premature optimization is the root of all evil etc...
However I have seen this optimization give a substantial performance increase in the following situation:
Method performing a very simple mathematical calculation with no memory accesses
Method being invoked millions of times per second in a tight inner loop
CPU bound application where every bit of performance mattered
If the above applies to you, it may be worth testing.
There is also one other good (and potentially even more important!) reason to use a static method - if the method actually has static semantics (i.e. logically is not connected to a given instance of the class) then it makes sense to make it static to reflect this fact. Experienced Java programmers will then notice the static modifier and immediately think "aha! this method is static so it doesn't need an instance and presumably doesn't manipulate instance specific state". So you will have communicated the static nature of the method effectively....
7 years later...
I don't have a huge degree of confidence in the results that Mike Nakis found because they don't address some common issues relating to Hotspot optimisations. I've instrumented benchmarks using JMH and found the overhead of an instance method to be about 0.75% on my machine vs a static call. Given that low overhead I think except in the most latency sensitive operations it's arguably not the biggest concern in an applications design. The summary results from my JMH benchmark are as follows;
java -jar target/benchmark.jar
# -- snip --
Benchmark Mode Cnt Score Error Units
MyBenchmark.testInstanceMethod thrpt 200 414036562.933 ± 2198178.163 ops/s
MyBenchmark.testStaticMethod thrpt 200 417194553.496 ± 1055872.594 ops/s
You can look at the code here on Github;
https://github.com/nfisher/svsi
The benchmark itself is pretty simple but aims to minimise dead code elimination and constant folding. There are possibly other optimisations that I've missed/overlooked and these results are likely to vary per JVM release and OS.
package ca.junctionbox.svsi;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;
class InstanceSum {
public int sum(final int a, final int b) {
return a + b;
}
}
class StaticSum {
public static int sum(final int a, final int b) {
return a + b;
}
}
public class MyBenchmark {
private static final InstanceSum impl = new InstanceSum();
#State(Scope.Thread)
public static class Input {
public int a = 1;
public int b = 2;
}
#Benchmark
public void testStaticMethod(Input i, Blackhole blackhole) {
int sum = StaticSum.sum(i.a, i.b);
blackhole.consume(sum);
}
#Benchmark
public void testInstanceMethod(Input i, Blackhole blackhole) {
int sum = impl.sum(i.a, i.b);
blackhole.consume(sum);
}
}
As previous posters have said: This seems like a premature optimization.
However, there is one difference (a part from the fact that non-static invokations require an additional push of a callee-object onto the operand stack):
Since static methods can't be overridden, there will not be any virtual lookups in runtime for a static method call. This may result in an observable difference under some circumstances.
The difference on a byte-code level is that a non-static method call is done through INVOKEVIRTUAL, INVOKEINTERFACE or INVOKESPECIAL while a static method call is done through INVOKESTATIC.
It is unbelievably unlikely that any difference in the performance of static versus non-static calls is making a difference in your application. Remember that "premature optimization is the root of all evil".
For the decision if a method should be static, the performance aspect should be irrelevant. If you have a performance problem, making lots of methods static isn't going to save the day. That said, static methods are almost certainly not slower than any instance method, in most cases marginally faster:
1.) Static methods are not polymorphic, so the JVM has less decisions to make to find the actual code to execute. This is a moot point in the Age of Hotspot, since Hotspot will optimize instance method calls that have only one implementation site, so they will perform the same.
2.) Another subtle difference is that static methods obviously have no "this" reference. This results in a stack frame one slot smaller than that of an instance method with the same signature and body ("this" is put in slot 0 of the local variables on the bytecode level, whereas for static methods slot 0 is used for the first parameter of the method).
There might be a difference, and it might go either way for any particular piece of code, and it might change with even a minor release of the JVM.
This is most definitely part of the 97% of small efficiencies that you should forget about.
In theory, less expensive.
Static initialization is going to be done even if you create an instance of the object, whereas static methods will not do any initialization normally done in a constructor.
However, I haven't tested this.
As Jon notes, static methods can't be overridden, so simply invoking a static method may be -- on a sufficiently naive Java runtime -- faster than invoking an instance method.
But then, even assuming you're at the point where you care about messing up your design to save a few nanoseconds, that just brings up another question: will you need method overriding yourself? If you change your code around to make an instance method into a static method to save a nanosecond here and there, and then turn around and implement your own dispatcher on top of that, yours is almost certainly going to be less efficient than the one built into your Java runtime already.
I would like to add to the other great answers here that it also depends on your flow, for example:
Public class MyDao {
private String sql = "select * from MY_ITEM";
public List<MyItem> getAllItems() {
springJdbcTemplate.query(sql, new MyRowMapper());
};
};
Pay attention that you create a new MyRowMapper object per each call.
Instead, I suggest to use here a static field.
Public class MyDao {
private static RowMapper myRowMapper = new MyRowMapper();
private String sql = "select * from MY_ITEM";
public List<MyItem> getAllItems() {
springJdbcTemplate.query(sql, myRowMapper);
};
};