Page 1 of 1

c++ v java

Posted: Thu May 10, 2007 6:04 am
by eman7613
Ok yall, if you want to continue the debate, keep it in here. :)

Get outa oodmb's raytracer topic cause its just rude :?

Posted: Thu May 10, 2007 11:25 am
by IanT
OK, I'm getting a bit bored of this one now (especially after the silly Quake example :wink: )

But the last benchmark posted by Deus...

First run on my Core2Duo gives a time of 17.0s.

Timing the loop within the program itself knocks off half a second (removing the startup-time for the JVM which is irrelevant for programs that run for any measurable amount of time).

Adding the "-server" option to the command-line invocation of the JVM brings it down to 10.8s (come on, everyone knows the server JVM is much quicker than the client version).

Then changing the code to the following...

Code: Select all

import java.io.*;
import java.util.*;

public class matrix {
    static int SIZE = 30;
    
    public static void main(String args[]) {
        long t0 = System.currentTimeMillis();
        int n = Integer.parseInt(args[0]);
        int m1[] = mkmatrix(SIZE, SIZE);
        int m2[] = mkmatrix(SIZE, SIZE);
        int mm[] = new int[SIZE * SIZE];
        for (int i=0; i<n; i++) {
            mmult(SIZE, SIZE, m1, m2, mm);
        }
        System.out.print(mm[0]);
        System.out.print(" ");
        System.out.print(mm[2 + 3 * SIZE]);
        System.out.print(" ");
        System.out.print(mm[3 + 2 * SIZE]);
        System.out.print(" ");
        System.out.println(mm[4 + 4 * SIZE]);
        System.out.println("" + (System.currentTimeMillis() - t0) + " ms");
    }
    
    public static int[] mkmatrix(int rows, int cols) {
        int count = 1;
        int m[] = new int[rows * cols];
        int ind = 0;
        for (int i=0; i<rows; i++) {
            for (int j=0; j<cols; j++) {
                m[ind++] = count++;
            }
        }
        return(m);
    }
    
    public static void mmult(int rows, int cols,
            int[] m1, int[] m2, int[] m3) {
        int ind = 0;
        int ind0, ind1, ind2, val;
        for (int i=0; i<rows; i++) {
            ind1 = 0;
            for (int j=0; j<cols; j++) {
                ind0 = i;
                val = 0;
                ind2 = ind1;
                for (int k=0; k<cols; k++) {
                    val += m1[ind0] * m2[ind2++];
                    ind0 += cols;
                }
                m3[ind++] = val;
                ind1 += cols;
            }
        }
    }
}
Brings it all down another 2.3s to 8.594 seconds (not bad for 5 minutes' work).

Anything using Java arrays is always going to be slow (because of the run-time range checking), that's why I personally avoid them in performance-critical code ... :wink:

Benchmarks really need do need to be run by someone with at least a modicum of knowledge about how to code and run Java efficiently :roll:

Ian.

Posted: Thu May 10, 2007 6:11 pm
by dogfin
I'll throw in my 2cents because I'm a well known thread killer.

As much as I hate java and its "Just in time to be late" compiler, (I'm a c/c++ man to the core), I have to admit that on modern hardware its only a few clocks slower than a c++ program for REAL WORLD code. I'm a man that hates benchmarks and other contrived examples because all they do is show how well something is at benchmarks and contrived examples.

On older hardware, the performance gap between c/c++ and java widends for many reasons, personally in my code its always been because c/c++ defaults to the native number sizes of the processor, whereas Java has specific sizes it has to forge out of whats available (such as 64bit long ints witch even my 2.4ghz xeon machine doesn't have native).

So to sum up, anyone that says Java is more than 1 to 5% slower than a c++ program is blowing propaganda out their butt.


dogfin -

Posted: Thu May 10, 2007 8:09 pm
by Deus
I can also upgrade my PC and beat your time.

Real world code is a word processor not a ray tracer. For specifc tasks the hand optimizations that C++ enables cannot be beat.

My argument was never that Java is incredibly slow and bad. It was to get the Java is as fast or faster than C out of your system.

By the way that square root has 0.1% error which is fine when it comes to normalizing normals which is not at all critical for the accuracy of a ray tracer. Most so called "physically correct" ray tracers like indigo for instance is still an approximation of most things and is not at all correct.

Posted: Thu May 10, 2007 9:16 pm
by IanT
dogfin speaks wisdom.
Deus wrote:I can also upgrade my PC and beat your time.
I was obviously looking at the relative times (was that not obvious?). The initial run on my PC (17.0) was only 3% quicker than on yours (17.6s) so definitely the same ballpark.
Deus wrote:Real world code is a word processor not a ray tracer. For specifc tasks the hand optimizations that C++ enables cannot be beat.
I agree. I'd never code a word-processor in Java because its string handling might be elegant but it's terribly slow.

The initial reason for this "discussion" was you claiming that Java would be at least 10 times slower for rendering. Then you came up with a few ray-tracing-related examples to support your point, which I then debunked. Now you're backtracking by saying ray tracing isn't a real-world application and therefore isn't relevant to the discussion!?
Deus wrote:My argument was never that Java is incredibly slow and bad. It was to get the Java is as fast or faster than C out of your system.
I never believed for a minute you thought it was bad. If your argument was never that it was incredibly slow, why did you come out with "10 times slower"?
Deus wrote:By the way that square root has 0.1% error which is fine when it comes to normalizing normals which is not at all critical for the accuracy of a ray tracer.
Firstly, it's extremely important. Vector normalisation isn't just used extensively for normals, it's also important for normalising ray direction vectors, or internal scale compensation for certain intersection tests. An innacuracy of the order 0.1% will screw up the calculation of t and i can assure you that this will show up as very visible artifacts.

Secondly, the normalisation of normals (especially in a renderer that uses triangle meshes predominantly) is most often performed only once ... either the one-off calculation of the triangle's geometric normal, or the sanity-checking of imported normals. It would be a false economy because implementing such an optimisation would hardly increase the performance of the core rendering loop.

Anyway, it's a moot point ... as I showed, the technique that you claimed was impossible in Java is actually possible so a naive renderer author would be free to make that choice (and then quickly go back to using Math.sqrt() once they've realised the error of their ways).
Deus wrote:Most so called "physically correct" ray tracers like indigo for instance is still an approximation of most things and is not at all correct.
I know exactly what goes on inside an unbiased renderer and the approximations that can't be avoided are all down to floating point accuracy (which is why I use double as much as possible, not float) and the extent to which real-world materials can be simulated inside a computer. Again, a 0.1% error in a square root calculation would be very daft, especially when such calculations make up no more than 1% of the overhead when rendering a medium-complex scene (see above Re: false economy).

Ian.