N
nicolasbock
I write programs at work to do numerical calculations. Those programs
are usually written in C. I recently started looking into Java and
found the language and its features very attractive. I figured that I
should give it a try and see whether it is suitable for numerical work.
So I went ahead and wrote a very simple matrix multiplication program
in C and Java and benchmarked them. To my disappointment, C turned out
to be about 1.5 to 2 times faster than Java.
Below more detail on what I actually did. I calculated the matrix
product of two random 800x800 matrices for int and double matrices. The
tests were run on a powerBook G4 1.33GHz. The C compiler was gcc-3.3
and the Java version I used 1.4.2_05. The C code was compiled with
optimization level 3 (-O3). I couldn't find anything equivalent for
javac, so I compiled the code presumably without optimizations or with
some default level of optimization. The runtimes I found were
int matrices
C (-O3): 15s
C (without -O): 33s
Java: 32s
double matrices
C (-O3): 28s
C (without -O): 47s
Java: 45s
Since the unoptimized C code (without specifying any -O level) runs
about as fast as the Java code I assume that I am looking at badly
optimized Java code.
Can I force the java compiler or the runtime engine to optimize my code
further?
Thanks, nick
The C program was
#include <stdio.h>
#include <stdlib.h>
#define N 800
#define M 800
int a [N][M];
int b [N][M];
int c [N][M];
int main ()
{
int i, j, k;
printf ("creating matrices a and b\n");
/* Initialize the two matrices. */
for (i = 0; i < N; ++i) {
for (j = 0; j < M; ++j) {
a[j] = (int) ((rand () / (double) RAND_MAX - 0.5) * 10);
b[j] = (int) ((rand () / (double) RAND_MAX - 0.5) * 10);
}
}
/* Multiply the matrices. */
printf ("multiplying them\n");
for (i = 0; i < N; ++i) {
for (j = 0; j < M; ++j) {
c[j] = 0;
}
}
for (i = 0; i < N; ++i) {
for (j = 0; j < M; ++j) {
for (k = 0; k < M; ++k) {
c[j] += a[k] * b[k][j];
}
}
}
}
The Java code was:
public class MatrixTestDirty
{
public static void main (String args [])
{
int N = 800;
int M = 800;
int a [][] = new int [N][M];
int b [][] = new int [N][M];
int c [][] = new int [N][M];
System.out.println ("creating matrices a and b");
/* Initialize the two matrices. */
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
a[j] = (int) ((Math.random () - 0.5) * 10);
b[j] = (int) ((Math.random () - 0.5) * 10);
}
}
/* Multiply the matrices. */
System.out.println ("multiplying them");
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
c[j] = 0;
}
}
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
for (int k = 0; k < M; ++k) {
c[j] += a[k] * b[k][j];
}
}
}
}
}
are usually written in C. I recently started looking into Java and
found the language and its features very attractive. I figured that I
should give it a try and see whether it is suitable for numerical work.
So I went ahead and wrote a very simple matrix multiplication program
in C and Java and benchmarked them. To my disappointment, C turned out
to be about 1.5 to 2 times faster than Java.
Below more detail on what I actually did. I calculated the matrix
product of two random 800x800 matrices for int and double matrices. The
tests were run on a powerBook G4 1.33GHz. The C compiler was gcc-3.3
and the Java version I used 1.4.2_05. The C code was compiled with
optimization level 3 (-O3). I couldn't find anything equivalent for
javac, so I compiled the code presumably without optimizations or with
some default level of optimization. The runtimes I found were
int matrices
C (-O3): 15s
C (without -O): 33s
Java: 32s
double matrices
C (-O3): 28s
C (without -O): 47s
Java: 45s
Since the unoptimized C code (without specifying any -O level) runs
about as fast as the Java code I assume that I am looking at badly
optimized Java code.
Can I force the java compiler or the runtime engine to optimize my code
further?
Thanks, nick
The C program was
#include <stdio.h>
#include <stdlib.h>
#define N 800
#define M 800
int a [N][M];
int b [N][M];
int c [N][M];
int main ()
{
int i, j, k;
printf ("creating matrices a and b\n");
/* Initialize the two matrices. */
for (i = 0; i < N; ++i) {
for (j = 0; j < M; ++j) {
a[j] = (int) ((rand () / (double) RAND_MAX - 0.5) * 10);
b[j] = (int) ((rand () / (double) RAND_MAX - 0.5) * 10);
}
}
/* Multiply the matrices. */
printf ("multiplying them\n");
for (i = 0; i < N; ++i) {
for (j = 0; j < M; ++j) {
c[j] = 0;
}
}
for (i = 0; i < N; ++i) {
for (j = 0; j < M; ++j) {
for (k = 0; k < M; ++k) {
c[j] += a[k] * b[k][j];
}
}
}
}
The Java code was:
public class MatrixTestDirty
{
public static void main (String args [])
{
int N = 800;
int M = 800;
int a [][] = new int [N][M];
int b [][] = new int [N][M];
int c [][] = new int [N][M];
System.out.println ("creating matrices a and b");
/* Initialize the two matrices. */
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
a[j] = (int) ((Math.random () - 0.5) * 10);
b[j] = (int) ((Math.random () - 0.5) * 10);
}
}
/* Multiply the matrices. */
System.out.println ("multiplying them");
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
c[j] = 0;
}
}
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
for (int k = 0; k < M; ++k) {
c[j] += a[k] * b[k][j];
}
}
}
}
}