Are static non member methods faster?

Okay,

Its late here-- is everyone as coinfused as I am?

I’ll look at it all tomorrow with a clearer head…

JK

Okay, somethinh WEIRD is happening the first time around the loop to the static calls. I don’t believe that it is really de-optimizing that. Ill look at it more tomorrow.

jk

[quote]In re client/server. On MacOSX I had no perceivable difference between -client and -server. It would be good for whoever else had reported OSX numbers to check my results to see if they line up. As I say, taken literally, my numbers show that static is (nominally) SLOWER on MacOSX.
[/quote]
Jeff, you are aware that there is no server VM on the Mac? Try it
Scott-Palmers-Computer:~ scottpalmer$ java -server -version
java version “1.4.1_01”
Java™ 2 Runtime Environment, Standard Edition (build 1.4.1_01-99)
Java HotSpot™ Client VM (build 1.4.1_01-27, mixed mode)
Scott-Palmers-Computer:~ scottpalmer$

If you dig deeper you will see that server VM is a symbolic link to the client VM library.

When you specify -server on the Mac it changes the memory allocation settings only. Why I know this is anyone’s guess.

Cas :slight_smile:


Scott-Palmers-Computer:~ scottpalmer$ ls -l /System/Library/Frameworks/JavaVM.framework/Libraries/
...
-rwxr-xr-x  1 root  wheel  2659672 24 Sep 03:01 libhotspot.dylib
lrwxr-xr-x  1 root  wheel       16 24 Oct 23:06 libclient.dylib -> libhotspot.dylib
lrwxr-xr-x  1 root  wheel       16 24 Oct 23:06 libjvm.dylib -> libhotspot.dylib
lrwxr-xr-x  1 root  wheel       16 24 Oct 23:06 libserver.dylib -> libhotspot.dylib
...

VMs all use the same code…

Now for settings…

Scott-Palmers-Computer:~ scottpalmer$ ls -l /System/Library/Frameworks/JavaVM.framework/Home/lib
...
-rw-r--r--   1 root  wheel      668 13 Sep 20:12 client_jvm.cfg
-rw-r--r--   1 root  wheel      668 13 Sep 20:12 jvm.cfg
-rw-r--r--   1 root  wheel      668 13 Sep 20:12 server_jvm.cfg
...

each file is identical except that the order of the VMs is changed so that -server or -client is specified first. (e.g. will be the default)… since these are already in files that are differentiated by ‘client’ and ‘server’ in the names… one wonders why they need to
do any of this, since the only way to pick the right file is to know which VM was specified… Not sure, as I don’t really know how this works.

In any case I can’t find a place where you can see what parameters are changed between client and server. I suspected that things like CompileThreshold etc are different.

Your question answered: Apple Java dev thing

Cas :slight_smile:

Inerestingly enough though, it benchamrks out more like “server” even though they say its a client VM.

Okay.

I made the fixes you suggested (the one wrong call and calling through the class name for static).

Didn’t change things much on my system under 1.4.2_02:

Server run:


java -Xcompile -server benchmarks.SimplifiedTest
Instance method (-705032721) 4126ms
Static method (-705032721) 4046ms
Instance method (-705032721) 4076ms
Static method (-705032721) 4326ms
Instance method (-705032721) 4016ms
Static method (-705032721) 4326ms

Client run:


java -Xcompile -client benchmarks.SimplifiedTest
Instance method (-705032721) 11276ms
Static method (-705032721) 9594ms
Instance method (-705032721) 11286ms
Static method (-705032721) 9594ms
Instance method (-705032721) 11576ms
Static method (-705032721) 10285ms

Source:



package benchmarks;


public class SimplifiedTest {

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 static void main(String[] argv) {
    SimplifiedTest t = new SimplifiedTest();
    for (int q = 0; q < 3; q++) {
      int v = 0;
      long start = System.currentTimeMillis();
      for (int i = 0; i < SIZE * 10; i++) {
        int a = t.iadd(i, 1);
        v = t.iadd(v, a);
        v = t.iadd(v, i);
        v = t.iadd(v, 5);
        v = t.iadd(v, v);
        v = t.iadd(i, v);
      }
      System.out.println("Instance method (" + v + ") " +
                         (System.currentTimeMillis() - start) + "ms");
      v = 0;
      start = System.currentTimeMillis();
      for (int i = 0; i < SIZE * 10; i++) {
        int a = SimplifiedTest.sadd(i, 1);
        v = SimplifiedTest.sadd(v, a);
        v = SimplifiedTest.sadd(v, i);
        v = SimplifiedTest.sadd(v, 5);
        v = SimplifiedTest.sadd(v, v);
        v = SimplifiedTest.sadd(i, v);
      }
      System.out.println("Static method (" + v + ") " +
                         (System.currentTimeMillis() - start) + "ms");
    }
  }
}


Writing the Vm guys now to ask about client…

jk

Turns out its exactly what I expected… a (known) bug in the client compiler :slight_smile:


Invocation of instance methods implies a null check and there’s a bug in the current null check eliminator in the client compiler which makes it unable to eliminate one of the null checks in the loop which accounts for the difference between the instance and static case. Otherwise the code is exactly the same for both cases. However as mike points out you aren’t really measuring what you think you’re measuring.

(Mike noted that, as SIZE is constant the compiler will fold down a lot of the logic because it can compute it ahead of time.)

Here is the general comment on this whole issue. Has a bit more detail then I was able to give but its basically the same answer.


As far as your question goes, here’s my take. Static methods have fixed properties, namely that they are statically bindable and don’t require null checks. Instance methods have dynamic properties, namely that they require null checks, which may be eliminated, and they may be statically bindable depending on optimizations in your vm and/or their accessibility, i.e. a private method is always statically bindable and final may be. So under many conditions they are interchangable performance-wise, it just depends on what your class hierarchy looks like and what the VM can prove about the nullness or non-nullness of your instance, and also of course what your method is going to do.

SO in a NON-BUGGY modern compiler static in of itself should make no appreciable difference. Anywhere wher it would make a difference is by definition somepalce you couldn’t use static to begin with (p[olymorphic behavior). Unfortunately the client compiler doesn’t yet qualify :frowning:

Excellent, thanks a lot for getting to the bottom of this. Is this known bug in the publicly accessible bug database? Got a Bug Id number? (I.e. is this something that people can vote for or is it an internal thing that we aren’t really supposed have to deal with?)

Is it expected to be fixed for 1.5?

[quote]Inerestingly enough though, it benchamrks out more like “server” even though they say its a client VM.
[/quote]
I just tell people that’s 'cause a PowerPC has an architecture that you don’t have to be ashamed of. cough Intel sucks cough
:wink:

Hey did you ever get to try this on a Sparc system?

Sparc? Whats a Sparc?

Just kidding. i have one on my desk i use for corporate things but at the moment most of my developmentt is mac/PC so it woudl be a pain to set up the test on my Sparc.

And lets face it, everyone reading this is a Client programmer so who really cares about Sparc? Rasie your hands… anyone… Bueller … anyone … ?

[quote]Excellent, thanks a lot for getting to the bottom of this. Is this known bug in the publicly accessible bug database? Got a Bug Id number?
[/quote]
Likely, but I’d have to search for it just like you :stuck_out_tongue:

I would assume so but thats a guess as I don’t have the VM team’s schedule infront of me.

Heh, I come back and you all have done the testing for me… Very interesting stuff!

Origionally, I was just coming from the perspective of the classic c/c++ debate that the added level of abstraction given by oop makes c++ slower than c. I’d actually seen some benchmarks that showed a very small but real difference in performance, but that was awhile ago and I certainly don’t remember the details. I was curious if the same idea applied in Java.

[quote]HOrigionally, I was just coming from the perspective of the classic c/c++ debate that the added level of abstraction given by oop makes c++ slower than c.
[/quote]
I figured that which was why I originally answered as I did, though these bums made me prove it (and found a bug in doing so. Good going guys.)

Forget what you know about C++ and performance. Late compilation makes it a whole new ball-game.