Are static non member methods faster?

I’m really glad newless clewbies is back… Here is what I want to do;

Make a static utility class with static methods that will operate on objects (think Math.cos() for example) for my 3d software renderer. For example functions that are called many times per frame such as:

Polygon3D utility.clipToFrustrum(Polygon3D poly);

So I’m curious if this completely wrong, non oop, non java approach would indeed be faster than the alternative correct approach;

newpoly = poly.clipToFrusrum();

(please don’t flame me for not using java2d tranforms and clipping stuff! This is a learning exercise!)

It isn’t wrong… but it might not be the best technique for your situation. Certainly the various Math methods make perfect sense as static methods… it would be dumb for example to construct a Double object just so you could call cos() on it…

You likely have a case where some static utility mehtods make sense, but in your one example… what defines the frustum? Should you have a Frustum object with a clipTo(Polygon3D) method?

You have near and far clipping planes and field of view… either they will need to be arguments to the clipToFrustum method, or you will need a single static frustum defined in the class, make the clip method part of the Polygon3D object, in which case it could take a Frustum argument, or there could be a single Frustum defined as a class variable, or do what I mentioned above and have the clipTo method an instance method of a Frustum class.

Lots of options and it isn’t always a matter of getting right or wrong… you have to imagine what will be best for the overall design.

Look at some of the cases where Sun has used static methods (SwingUtilities, Math, etc…) and try to reason why they wre done as static methods. you should likely have the same kind of reasons for your Polygon3Dutility methods

edit
P.S. Speed should not be a concern at all when choosing to implement something as static vs. instance methods. (optimization generally comes later - unless you know from experience and have are confident that one choice will definately be TOO slow.)

To answer to the subject’s question: No, static methods aren’t faster. The Hotspot VM (Sun’s Java virtual machine) should be clever enough to optimize (compile, inline, de-virtualize) methods automatically based on their usage.

And don’t fool yourself using micro-benchmarks like calling one method in a tight loop a million times or so. Such kind of benchmark isn’t generally representative and gives the VM no chance to collect usage data for its optimisation.

[quote] And don’t fool yourself using micro-benchmarks like calling one method in a tight loop a million times or so.
[/quote]
Yeah, but thats kind of what a rendering loop is though; only with a few more functions/methods. In my mode7 applet the fps does increase by about 2-4 fps after the first few seconds (this is using a regular member drawing method of a normal class) I assumed that was due to the vm optimizing. Hmm, guess I’ll have to try and see.

In a precompie\led language like C++, definign a method as static tells the compiler it can be sure that call points calling the method are monomorphic (their destination is a single dterminable address) and thus it allwos for better inlining.

Java JITs however don’t need this clue. Because they have run-time info available they can (and hotspot does) determine if a call point is monomoprhic based on the currently loaded classes adn do the same sort of inlining. Thus declaring somethign static has no advantage over simply not using it in an overloaded manner.

(If a late load changes the call point to be truely polymorphic, with multiple possible destinations, the opimizations are backed out automatically by the VM.)

JIT certainly needs this clue. While it can manage to inline code without it, it’s job is a lot easier if it knows that given call is private/static/final. Generated code will be a bit better (no need for fallback clauses), jit time is smaller.

This is certainly nothing to worry about in J2EE apps or even desktop J2SE apps, but for game apps, it might be a difference. Certainly static/private/final methods are not slower - so you cannot lose by using them.

Any simple benchmark will not give you the true answer - for 1-2 class code, jit can do any optimalization it wants. For thousand classes, there is only limited amount of magic that can be done in real time and any hints you can give to jit certainly can help.

This may be true. But it is still advisable to use ‘static final’ only for methods that truly SHOULD be static and final. Then if performance is an issue, profile and tweak. If making something static final improves the measured performance at that stage, go for it. Don’t design that way up-front unless you know you have to. It just ties your hands from doing other kinds of refactoring and algorithms too early in the process.

I’m in no way proposing using final/static everywhere, just for sake of possible speed - I was adressing statement that it is totally not needed for jit.

As for final, it should be probably used only for security/design reasons (you really do not want to allow subclassing of given class/method). For other things, I try to stick to following guidelines, which IMHO are quite acceptable from both performance and design side:

  1. If something does not touch state of object, make it static. While having such functions (method is not really good name) is non-OO, making it a member method will not make it any more OO. For me, main benefit is reuse (don’t have to create proxy object just to call it) and clarity (I’m sure that static method do not modify state of object).

  2. If you need helper method for other methods working on object, make it private. Again, main benefit is not cluttering public namespace with methods which really have meaning only inside class body, possibly leaving object in half-cooked state.

  3. Use final only for security and to protect fellow programmers from overriding targeting mechanism of gun - to protect innocent feet. Security reasons are obvious (vide String), protection - only in most dangerous cases, especially if there is some kind of voodoo magic going behind.

  4. and 2) have a nice effect of being performance-friendly - both static and private methods can be inlined with ease. While this pleases my clock-counting part of personality, main reasons are ones stated above - clarity in most cases :wink:

I wasn’t trying to argue or anything - I just wanted to make it clear for the newbies.

To add to your list, another point for not using static is if you might need to override the method, even if it doesn’t touch the object, it might want to do things differently when called in a different context - e.g. called from another method that can not be static. It’s less common, but it can happen… specially with singletons.

[quote]JIT certainly needs this clue. .
[/quote]
I can state that it makes no measurable or precievable difference to Hotspot 's JIT.

Obviously I can’t 100% state that all JITs perform as well. (You can write a crappy anything, including a JIT.)

JK

I have done a simple benchmark and static methods are at least umpteen percent faster than instance ones - for simplest case, where Hotspot for sure can inline everything.

Indeed, I was not able to see a difference between public, private and public final instance methods - so it seems that for this few lines benchmark, Hotspot is smart enough to devirtualize a call, but not smart enough to make it as fast as static method.

I wonder if -XX:+PrintCompilation could help shed some clues?

Hey Jeff! Is there any chance you can find out what the information means before the method name in the output of +PrintCompilation ? I can guess some of it, but it would be nice to know for sure.

[quote]I have done a simple benchmark and static methods are at least umpteen percent faster than instance ones - for simplest case, where Hotspot for sure can inline everything.
[/quote]
Can you
(a) Give us the benchmark ?
(b) Quantify “umpteen” ?

[quote]I wonder if -XX:+PrintCompilation could help shed some clues?

Hey Jeff! Is there any chance you can find out what the information means before the method name in the output of +PrintCompilation ? I can guess some of it, but it would be nice to know for sure.
[/quote]
Sure Ill ask the Vm guys…

JK


public class Test {

  public static final int SIZE = 100000000;

  public int iadd(int a, int b) {
    return a + b;
  }

  public static int sadd(int a, int b) {
    return a+b;
  }


  public void itest() {
    int v = 0;
    for ( int i =0; i < SIZE; i++ ) {
      v = iadd(i,iadd(v,iadd(5,iadd(iadd(v,iadd(i,1)),i))));
    }
    System.out.println(v);
  }

  public void stest() {
    int v = 0;
    for ( int i =0; i < SIZE; i++ ) {
      v = sadd(i,sadd(v,sadd(5,sadd(sadd(v,sadd(i,1)),i))));
    }
    System.out.println(v);
  }

  public static void main(String[] argv) {
    Test t = new Test();
    t.itest();
    t.stest();
    long start = System.currentTimeMillis();
    for ( int i =0; i < 10; i++ )
      t.itest();
    System.out.println("Instance method " + (System.currentTimeMillis()-start) + "ms");
    start = System.currentTimeMillis();
    for ( int i =0; i < 10; i++ )
      t.stest();
    System.out.println("Static method " + (System.currentTimeMillis()-start) + "ms");
  }
}

Instance method 6265ms
Static method 4328ms

In this case, umpteen means 30% faster, or 45% slower. This is a result for client jvm 1.4.2, server jvm is a lot better
(around 2500ms, with 50-60ms penalty for instance method, so this means around 2% difference). But let’s focus on client version :slight_smile:

:o The gap is even bigger for me : I got 8900ms with instance method vs 2530ms with static method !!

I’m running Java Hotspot client VM ( 1.4.2-b28 ) under Win98 on a P4 2.8C.

So what is the explanation now ;D ?

On my PC (1GHz P3, jre 1.4.1_b01):

using client VM:
instance: 13469ms
static: 12428ms

using server VM:
instance: 13530ms
static : 12478ms

difference is about 7-8 percent and the server VM is slightly slower here (??? to be honest, this is not the only case where the client outperforms the server on my machine although the difference is very small in this case)

In any way, the difference between static and instance calls seems to be too small to care much, really (although it would of course be nice if there was no difference at all).

[quote]In any way, the difference between static and instance calls seems to be too small to care much, really .
[/quote]
Too small on your computer, not on my or overnhet.

I’m in no way advocating using static methods for speed here. I’m just fighting a statement that Hotspot can optimize such things to no difference - it can be clearly seen that it cannot. Fact that some processors are smart enough to optimize slower case or stupid enough to not optimize faster route does not change the fact that one some processors difference is noticeable.

Yes, there is definitely a difference. On my PC a very small difference but you’re right there is a difference.

GCJ compiled exe:

Instance: 127003ms
Static: 123207ms

Ouch! (GCJ runs 10x as slow) :-[

On P4 1.6GHZ, j2sdk1.4.2beta1:

instance: 7960 ms; static 4180

A question though - and someone may want to double check
on this please !

Is the “v” computation overflowing both int (and long) ? And would
that by any remote chance affect the timings ?

I modified Artur’s code to “return 0” instead of “return a+b”
and got the following results:

instance: 2970 ms; static 2190 ms