I need to convert one-dimensional and two-dimensional Java arrays of double
elements through JNI to/from the ALGLIB real_1d_array
and real_2d_array
in C/C++, respectively. Right now, the process is as follows:
Use the JNI
GetDoubleArrayElements()
to obtain a contiguous vector ofjdouble
in C/C++. On my machine, this always produces a copy, i.e. JNI sets the last argument of this call,jboolean isCopy
, toJNI_TRUE
.Allocate a C/C++ vector of
double
and copy elements from the JNI vector ofjdouble
to it. Note that, in general, there is no guarantee that thejdouble
type is the same as thedouble
type, so a cast todouble
is necessary when copying array elements one by one. (Is there a clean way to determine thatjdouble
is indeed the same asdouble
, either at compile time or runtime?)Instantiate an ALGLIB
real_1d_array
orreal_2d_array
, respectively. As far as I can tell from the ALGLIB code, this creates anae_matrix
of dimensions (0, 0) internally held by the array.Copy the array elements from the C/C++ contiguous vector of
double
to the ALGLIB array using thesetcontent()
method. As far as I can tell from the code, this resizes the internallly-heldae_matrix
appropriately and copies elements one by one into that matrix. It looks like in the case of a two-dimensional matrix, the first dimension is a vector of pointers to linear vectors ofdouble
, so that elements are stored non-contiguously in an array of one-dimensional arrays (similar to Java).Use ALGLIB to perform the desired computations using the real arrays.
To copy results back to JAVA arrays through JNI, reverse the process. Elements of the ALGLIB real arrays are only accessible through methods. For one-dimensional arrays, there is a
getcontent()
method that returns a pointer to a contiguous vector ofdouble
. For two-dimensional array, throughoperator []
that returns a pointer to a contiguous row. As before a one-by-one element copy with a cast tojdouble
is used.
As you can see, there is plenty of copying involved. For small arrays, this is not a big deal, but for larger ones this gets quite expensive in terms of memory and CPU.
Is there a way to speed things up without relying on the knowledge of internal structures of ALGLIB, which may be subject to change?