Skip to main content

Array performance

6 replies [Last post]
larryhamp
Offline
Joined: 2006-08-10

I have been doing some testing of the performance of arrays in Mustang (b88). I made some interesting observations:

-C# array performance better than client and server VM performance of Mustang on Athlon x2 3800+

-Server VM *slower* than client VM on the Athlon (The reverse is the case on the Pentium D dual core)

-Server VM runs faster if I use Jikes to generate my bytecode (odd). This only happends on the Athlon.

-C# faster than Mustang client VM on Pentium D.

-Server VM faster than C# on Pentium D only.

-IBM JDK 1.4.2 faster than all other VMs I tested (only tested the IBM VM on the Athlon).

I would really appreciate some feedback from the HotSpot team on these observations.

Mustang b88 32bit on Windows XP sp2 (32 bit) 1GB RAM used for all tests. Tests conduced with Athlon 64 x2 3800+ and Pentium D 830 dual core 3.0 GHz.

Results as follows:

AMD Athlon 64 x2 3800+ :

C#.NET v2.0: 2680 milliseconds

(bytecode generated by javac)
IBM JDK 1.4.2: 2015 milliseconds
Sun JDK 6 client: 3187 milliseconds
Sun JDK 6 server: 6547 milliseconds (compared to 3500 with Jikes)

(bytcode generated by Jikes)
IBM JDK 1.4.2: 2015 milliseconds
Sun JDK 6 client: 3140 milliseconds
Sun JDK 6 server: 3500 milliseconds (faster than with javac, why?)
Sun JDK 6 server with (-XX:CompileThreshold=5000000): 3365 milliseconds

Intel Pentium D 3.0 GHz dual core:

C#.NET v2.0: 3256 milliseconds

(bytecode generated by Jikes)
Sun JDK 6 client: 3748 milliseconds
Sun JDK 6 server: 2593 milliseconds
Sun JDK 6 server (with -XX:CompileThreshold=5000000) 2608 milliseconds (slower if used on Intel)

Source code:

public class ArrayTest {
public static void main(String[] args) {

int[] test = new int[10000000];
for (int i = 0; i < 10000000; i++) {
test[i] = i;
}

//loop through test repeatedly
for (int j = 0; j < 15; j++)
{
long startTime = System.currentTimeMillis();
String o = null;
long count =0;
for (int k=0; k<100; k++) {
for (int i = 0; i < 10000000; i++) {
count += test[i];
}
}
long endTime = System.currentTimeMillis();
System.out.println((endTime-startTime)+" milliseconds");
System.out.println(count);
}

}
}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
larryhamp
Offline
Joined: 2006-08-10

Thanks for the feedback, but even with the refactorings, and warmup loops etc. the following STILL holds:

1. C# is faster than Mustang client for arrays and ArrayLists (but not for HashMap, TreeMap tests).

2. Jikes produces bytecode which runs faster on the first run.

These are the questions which need to be answered.

BTW The server compiler is now faster on the Athlon now that I moved most of the code out of the main method. It makes a big difference.

Message was edited by: larryhamp (correction made)

spdenne
Offline
Joined: 2006-02-15

You might find this thread interesting too:
http://forums.java.net/jive/thread.jspa?threadID=15243

spdenne
Offline
Joined: 2006-02-15

A couple of suggestions:
1) extract the code you are timing, to a method, so it may be recompiled, and the new version used.
2) iterate up to test.length instead of 10000000 to help the jvm figure out that the array bounds do not need to be checked.

sjasja
Offline
Joined: 2004-08-15

spdenne's first suggestion above is excellent advice for microbenchmarking. I don't get any difference in either direction from the second suggestion though.

For me, JDK 5.0 -server:
Original program: 7 seconds
Extract to method: 4 seconds.

Java SE 6 is a bit faster
[code]
public class ArrayTest {
public static void main(String[] args) {
for (int j = 0; j < 15; j++)
doit();
}

static void doit()
{
int[] test = new int[10000000];
for (int n = 0; n < 10000000; n++)
test[n] = n;

long startTime = System.currentTimeMillis();
long count =0;
for (int k=0; k<100; k++) {
for (int n = 0; n < test.length; n++)
count += test[n];
}

long endTime = System.currentTimeMillis();
System.out.println((endTime-startTime)+" milliseconds");
System.out.println(count);
}
}
[/code]

Message was edited by: sjasja (renamed loop index because lame forum software insists on interpreting left-bracket-i-right-backet as start italics, even inside pre and code.)

spdenne
Offline
Joined: 2006-02-15

Another option is to use:[code]
for (int i : test) {
count += i;
}
[/code]It seems to compile to more bytecode, but run at about the same speed.

Note that you are also microbenchmarking the int to long extension. If count is an int, you get overflow, but the code runs much faster.

olsonje
Offline
Joined: 2005-08-10

IBM's jvm has had a metric ton of optimization done to it because they are still developing it. Last time I heard, they where just now starting to release a Java5 jvm, but I haven't heard much about it. They are constantly years behind the main stream releases and usually the end result is a seriously optimized jvm, yet, the cost of such a thing is being years behind the current sun jvm.

As for the times, yea its slow but I don't have much to say outside of that.