Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (483)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (550)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2 3
  ignore  |  Print  
  Are static non member methods faster?  (Read 14262 times)
0 Members and 1 Guest are viewing this topic.
Offline nonnus29

Senior Member




Giving Java a second chance after ludumdare fiasco


« Posted 2003-10-22 00:54:19 »

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!)
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #1 - Posted 2003-10-22 02:47:41 »

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

Offline sma

Junior Member





« Reply #2 - Posted 2003-10-22 21:26:55 »

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.

.: Truth Until Paradox!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline nonnus29

Senior Member




Giving Java a second chance after ludumdare fiasco


« Reply #3 - Posted 2003-10-23 20:46:43 »

Quote
And don't fool yourself using micro-benchmarks like calling one method in a tight loop a million times or so.


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.
Offline Jeff

JGO Coder




Got any cats?


« Reply #4 - Posted 2003-10-28 07:40:59 »

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

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline abies

Senior Member





« Reply #5 - Posted 2003-10-28 08:01:39 »

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.

Artur Biesiadowski
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #6 - Posted 2003-10-28 12:15:11 »

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.

Offline abies

Senior Member





« Reply #7 - Posted 2003-10-28 13:42:58 »

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.

1) 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

Artur Biesiadowski
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #8 - Posted 2003-10-28 17:45:47 »

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.

Offline Jeff

JGO Coder




Got any cats?


« Reply #9 - Posted 2003-10-28 19:18:38 »

Quote
JIT certainly needs this clue. .


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

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline abies

Senior Member





« Reply #10 - Posted 2003-10-28 19:35:46 »

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.


Artur Biesiadowski
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #11 - Posted 2003-10-28 21:44:14 »

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.

Offline Jeff

JGO Coder




Got any cats?


« Reply #12 - Posted 2003-10-28 23:53:33 »

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.


Can you
(a) Give us the benchmark ?
(b) Quantify "umpteen" ?

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Jeff

JGO Coder




Got any cats?


« Reply #13 - Posted 2003-10-28 23:54:14 »

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.


Sure Ill ask the Vm guys...

JK

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline abies

Senior Member





« Reply #14 - Posted 2003-10-29 05:35:39 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
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 Smiley


Artur Biesiadowski
Offline overnhet

Junior Member




Java games rock!


« Reply #15 - Posted 2003-10-29 06:59:25 »

Shocked 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  Grin ?
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #16 - Posted 2003-10-29 08:02:43 »

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 (Huh 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).

Offline abies

Senior Member





« Reply #17 - Posted 2003-10-29 08:22:38 »

Quote
In any way, the difference between static and instance calls seems to be too small to care much, really .


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.


Artur Biesiadowski
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #18 - Posted 2003-10-29 09:27:28 »

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) Embarrassed

Offline NVaidya

Junior Member




Java games rock!


« Reply #19 - Posted 2003-10-29 10:16:00 »


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

Gravity Sucks !
Offline overnhet

Junior Member




Java games rock!


« Reply #20 - Posted 2003-10-29 10:55:17 »

With the "return 0" change, I get

* client JVM : instance=1760ms ; static=1260ms
* server JVM : instance=0ms ; static=0ms

And now, a little bit more interesting...
When I change nested iadd/sadd calls with only 1 call (v = iadd(i,1); for example), I get no difference between static and instance :

* client JVM : instance=1650ms ; static=1650ms
* server JVM : instance=0ms ; static=0ms

So on my JVM version performance difference is either due to int overflow or to nested calls.
Offline NVaidya

Junior Member




Java games rock!


« Reply #21 - Posted 2003-10-29 11:22:42 »

Yes, and I had obtained such similar results too with
i/sadd(1,2); So, would this breakdown be any reasonable ?
Overhead simply due to declaring a function instance/static -
looks like there is none. Any extra optimization that the
JVM would make use of if the function does a little more
non-trivial work. I don't want to get into areas where I'm not an
expert Smiley

Edit: Of course, hard to quantify what would happen in a real
full fledged application when the JVM would be highly loaded - standard disclaimer !

Gravity Sucks !
Offline abies

Senior Member





« Reply #22 - Posted 2003-10-29 11:42:46 »

Less nested calls you make, less difference between these two you will see. Overhead of loop is quite big, so you need at least few calls to measure a difference.

As far as nesting is concerned, please try following code
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
public void itest() {
    int v = 0;
    for ( int i =0; i < SIZE; i++ ) {
      int a = iadd(i,1);
      v = iadd(v,a);
      v = iadd(v,i);
      v = iadd(v,5);
      v = iadd(v,v);
      v = iadd(i,v);
    }
    System.out.println(v);
  }

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


It gives 19828ms for instance, 5750ms for static (this is not comparable to my previous results, as I use different computer now).

4x difference is even better to show the problem, so maybe we can start to talk about 'corrected' benchmark now Smiley

I have done printout on purpose - without it, method is too trivial to optimize. Even with printout, it is possible to compute statically, but I hope that thanks to the overflow it is not something that normal compiler will try to do.

This benchmark is really trivial, to show that even in simpliest cases Hotspot shows difference between such calls. With more complicated ones, it can get only worse.

As for making loop shorter, please be sure to use both v and i inside it. If you don't modify v, it is possible to just run last iteration of loop. If you don't use i, all iterations give same result. So v = iadd(v,i) is absolutely bare minimum for anything reasonable - but you need to keep adding instruction long enough to server Hotspot stop optimizing it completly (we are not testing Hotspot in general, we are testing difference between static and instance method invocation speed).

Artur Biesiadowski
Offline overnhet

Junior Member




Java games rock!


« Reply #23 - Posted 2003-10-29 12:21:30 »

Looks like I've a lot to learn in performance tuning and How To Write Correct Benchmarks  Grin

With those new methods, I got the same results as in my first post :

* client JVM : instance= 8680ms ; static=2520ms
* server JVM : instance= 980ms ; static=940ms

Huh
Offline NVaidya

Junior Member




Java games rock!


« Reply #24 - Posted 2003-10-29 12:30:32 »


One more point for your second version (P4 1.6GHz,
j2sdk1.4.2beta1):

instance: 10380ms; static: 5330ms

Keep at it !

Gravity Sucks !
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #25 - Posted 2003-10-29 12:43:15 »

Now I get the following (much varying) results:

1.4.1_01 client:
Instance method 28311ms
Static method 12287ms

1.4.1_01 server:
Instance method 4316ms
Static method 4286ms

GCJ compiled .exe:
Instance method 133893ms
Static method 123427ms
(oh my god  Roll Eyes Must be a bug)

Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #26 - Posted 2003-10-29 15:44:39 »

With the latest routines posted above on OS X 10.3  Java 1.4.1_01

Instance method 13527ms
Static method 12005ms

about 12% difference.

Offline Jeff

JGO Coder




Got any cats?


« Reply #27 - Posted 2003-10-29 21:14:25 »

CAVEAT REMINDER:  -XX flags are non standard, non-published flags mostly intended for the Sun development guys and subject to chnage or elimination without notice.

Having said that, here's your answer:

The format is undocumented and unsupported (-XX flag).
It will change as more/different properties are tracked, and please
don't ask why '*' is used for a native method instead of 'n'.

###                                  compile ID, printed using at least 3 columns
  %                                 compile for On Stack Replacement, OSR, of interpreter frame
  *                                 method is native
   s                                method is synchronized
    !                               method has exception handler
     b                              interpreter has been blocked until compile completes
      1                             compile without full optimization, tier1
         method_name..              without signature
                       @ bci %d     For OSR compiles, bytecode index at which replacement will happen
                       (%d bytes)   Bytes of bytecodes in method (does not include inlined methods)


Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Jeff

JGO Coder




Got any cats?


« Reply #28 - Posted 2003-10-29 21:17:24 »

Quote
Shocked 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  Grin ?


Well to begin with, I see NO VM warmup.  A potentially fatal flaw in ANY Vm benchmark.

Are you running this with the -compile flag?

Jeff

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Jeff

JGO Coder




Got any cats?


« Reply #29 - Posted 2003-10-29 21:30:40 »

Okay,

I did 2 things to fix this benchmark (code below).

(1)  I removed the prints in the middle of the tests. No no no bad bad bad.  IO blocks in the system and will dominate your results and destroy their meaning.

(2) I put ANOTHER "non-static" test AFTER the static test.  This illustrates exactly what I thought was going on, your test was order dependant because you weren't fully warming up the VM prior to starting your tests.

Results on my mac show these calls ARE identical, within a pretty meaningless margin of error:

results:
1  
2  
3  
Instance method 10366ms
Static method 9154ms
Instance method 9142ms


Gee, based on your benchmark static methods are SLOWER!

(Just kidding, its obviously noise or the tail-end of the wram-up issue effecting the second test.)

Code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
package benchmarks;

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++ ) {
      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");
    start = System.currentTimeMillis();
    for ( int i =0; i < 10; i++ ){
      t.itest();
    }
    System.out.println("Instance method " + (System.currentTimeMillis()-start) + "ms");
  }
}


next?

JK

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Pages: [1] 2 3
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CopyableCougar4 (18 views)
2014-08-22 19:31:30

atombrot (28 views)
2014-08-19 09:29:53

Tekkerue (25 views)
2014-08-16 06:45:27

Tekkerue (23 views)
2014-08-16 06:22:17

Tekkerue (15 views)
2014-08-16 06:20:21

Tekkerue (22 views)
2014-08-16 06:12:11

Rayexar (63 views)
2014-08-11 02:49:23

BurntPizza (39 views)
2014-08-09 21:09:32

BurntPizza (31 views)
2014-08-08 02:01:56

Norakomi (38 views)
2014-08-06 19:49:38
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!