In general, I like programming in Java much more than C++ mostly because linking of libraries is much easier (no "dependency hell") and because there are great packages with a lot of functionality out of the box. I also like java tools like jMonkey and Processing.
However, I very often do something with physics where I need fast math with 3D vectors. And I didn't find any convenient way how to do it in Java both performance efficient and readable ( C++ constructs like macros, overloaded operators, structs, and passing variables by reference are very helpful tools for this purpose ).
For example leapfrog integrator of a mass particle in central forcefield. In C++ I can make something like this ( using overloaded operators for type float3 ):
float ir2 = 1.0f/dot(vec_pos,vec_pos);
float ir = sqrt(ir2);
float3 vec_G = -vec_pos / (ir2*ir);
vec_v += vec_G*dt;
vec_pos += vec_v*dt;
readable code in Java would look like:
float ir2 = 1.0f/vec_pos.mag2();
float ir = sqrt(ir2);
float3 vec_G = vec_pos.mult( -ir2*ir);
vec_v .addLocal( vec_G.multLocal( dt ) );
vec_pos .addLocal( vec_v.mult ( dt ) );
which is not very good for performance since it allocates new objects as temporary variabales where "Local" method is not possible to use. I can optimize it by defining new methods for fused-multiply-add like:
float ir2 = 1.0f/vec_pos.mag2();
float ir = sqrt(ir2);
float3 vec_G = vec_pos.mult( -ir2*ir);
vec_v .addLocal_vec_times_scalar( vec_G, dt );
vec_pos .addLocal_vec_times_scalar( vec_v, dt );
But it is not very convenient to define specialized method for all possible combinations of arithmetic operations with float3 vector ... like:
float3.addLocal_vec1_times_vec2_times_scalar()
An other strategy how to avoid allocation of temporary objects on-the-fly is to define this temporary variables once as some static global variables (which is not nice coding style) or as properties of enclosing class like:
class asteroide{
// state variables
float3 vec_pos;
float3 vec_v;
// temporary variables
float3 vec_G,vec_dpos;
void update_leapfrog(float dt){
float ir2 = 1.0f/vec_pos.mag2();
float ir = sqrt(ir2);
vec_G .set_mult( vec_pos, -ir2*ir );
vec_v .addLocal( vec_G.multLocal( dt ) );
dpos .set_mult( vec_v, dt );
vec_pos .addLocal( dpos );
}
}
In both cases there is performance cost for dereferencing pointers to this objects. It also make asteroide object more memory consuming.
There is also performance penalty for calling object methods (even if I try to make them "final" and "static" so JIT can inline them effectively ). According to my test using float3.mult() is 2-3x slower than just multiplication of 3 float.
So I often end up writing complex vector algebra computations using just float , to avoid this performance penalties. :((( But than it is not readable at all. Doing rigid body dynamics and aerodynamics computation in this way is pain in the ass. It is as bad as Fortran77 programs 40 years ago !!!! ( just for curiosity see eg. code of Xfoil http://web.mit.edu/drela/Public/web/xfoil/ )
What strategy you recommend for doing vector math in Java both performance efficient and convenient (~readable)?