Jon Harrop said:
My ray tracers are on this page:
http://www.ffconsultancy.com/free/ray_tracer/languages.html
My straightforward C implementation is almost as slow as Java on this
test.
Well that's quite odd as well then...hm..
Ok, I was completely wrong there. I just reimplemented the OCaml ray
tracers
using objects instead of records for 3D vectors and the time taken went
from 3.5s up to 26.4s!
No idea why...
Object maintenance is just way more costly than records/tuples. The latter
is little more than a glorified 2d array.
I'm under the impression that there are no decent alternatives in Java: no
tuples, no records, no variant types and certainly nothing more
sophisticated.
This is true, it's primary types or objects, there's no real middle ground.
But in almost all cases you can design things in such a way that the object
overhead is minimal. I showed you my source that was a few times faster than
the original, but you can even go further and, for example, implement 3d
vector stacks. In case you're unfamiliar with those, it's a very uncommon
way to reduce object overhead, you'd do something like :
stack.push(0, 1, 1); // push a vector on the stack
stack.push(3, 2, 2); // push another one
stack.normalize(); // normale last vector we pushed
double d = stack.dot(); // get dot product
as you can see, no object creation is necessary at all both in this snippet
and the actual stack code. Alternatively, you'd have to do :
Vec v1 = new Vec(0, 1, 1); // new object
Vec v2 = new Vec(3, 2, 2); // new object
Vec v3 = v2.normalize(); // new object
double d = Vec.dot(v1, v3);// finally!
Another quite elegant property of the stack is that it doesnt care how many
vector a method needs as parameters, and that it wouldnt even care if you
use a single scalar or a vector :
stack.push(1, 1, 1);
stack.push(5);
stack.scale();
==
stack.push(1, 1, 1);
stack.push(5, 5, 5);
stack.scale();
This is a more efficient way to handle vectors in languages where object
managment slows things down. Obviously it does come at the cost of being a
fair bit less natural to use, especially if the language has operator
overloading, you'd go from :
a = v1 + v2
to
push(v1); push(v2);
a = add();
Anyway, food for thought perhaps?
Well, Java beats OCaml when the OCaml is made to use objects. This is
probably another reason why OCaml programmers rarely use OO.
Fair enough, but OO has a few big advantages, so it's not something most
people are willing to not use for some extra speed.
I really think they should. Although I wouldn't have written a book on it
if
I didn't think so.
AHA!, you wrote a book, i was wondering why you were so happy with OCaml
Well it is a nice language, i'll just be happy you didnt write a book called
"GW-BASIC for Scientists"..
I'm willing to accept that this benchmark hits weak points of Java. It
hits
weak points of SML/NJ as well.
Finally
...and like i showed you, there are some workarounds to most
bottlenecks, all of which at the cost of some code clarity.
I just tried it again and I get 8.3s with -client and 7.8s with -server.
That's only 6% faster. Maybe if I did a longer run...
Just did it again and got 34.7s -> 29.8s. That's 14% faster, which is more
like it.
Perhaps it's also related to the OS, i run on good ol' hardly working
Windows...i'm lazy like that.
All of the implementations use a linked list.
Okay, JCF is still pretty slow in my experience, but it shouldnt matter too
much.
I'm sorry, they have been public the whole time. I gave the link in the
original post that started this thread but I've updated it with the page
at
the top of this post.
I know, my fault, i lost the first few posts where the links are. As you
know i found them yesterday and sent you the modded code.
I have a hunch that Java will be as good as C at handling float arrays
because it doesn't require GC and object creation. Unfortunately I don't
have many applications that require this, even as a computational
scientist.
Well, if you use vector stacks you would, or if you move to the realm of
global illumination you would (think particle arrays for photon mapping).
And it's also about simple loops, math etc.
What i was considering is make a program that raytraces a sphereflake on the
fly in such a way that the flake does not have to be pre-generated, but
instead it's sphere hierarchy is dynamically traversed during the
raytracing. I can imagine that especially in computational science not all
data can be generated in memory before calculations (such as raytracing) can
be done, some data sets are simply too large and can be generated on the fly
when needed. The only issue may be that my math may not be up for the task
Remon van Vliet