Jump to content
Excelsior Forums
Sign in to follow this  
metaphysicist

Inefficiency of Pointer.CreateArray

Recommended Posts

Hi,

I have to repeatedly send large chunks (32Kb) of audio data in/out of Java using xFunction. The data chunks are passed in/out using char[] pointer in an xFunction structure.

When I am sending data out I use

int srb_buflen = buf.length

Pointer srb_bufpointer = (Pointer)Argument.create("char*", buf);

When I am receiving data I provide an empty buffer to the native function using the exact same procedure:

int srb_buflen = buf.length

Pointer srb_bufpointer = (Pointer)Argument.create("char*", buf);

When the function returns I need to get access to the newly filled data, so I use:

char[] outBuf = (char[]) srb_bufpointer.createArray(srb_buflen);

BUT when I profile my app I find this exremely inefficient in terms of speed and memory - it's very slow!

Because the buffer is 32Kb (32*1024 elements) does this mean that CreateArray has to fill from the values of 32*1024 Character objects?

How can I avoid his inefficiency? - a typical transfer for me could be 10MB of 32Kb blocks.

:huh:

Share this post


Link to post
Share on other sites

Hi,

Actually, xFunction is designed not for efficience, but for ease-of-use and reliability. Particularly, while sending a data, initial Java array is copied into the internal buffer, in order to avoid concurrent modification and GC issues.

In your case, I would recommend to use 'clean' JNI. However, there are some 'tricks' those potentially may increase the performance of your code.

First of all, use 'int' array instead of 'char', because of the Java 'int' type has full correspondance with C 'long' type, so no conversion is needed. Surely, the buffer size should be aligned to 4 bytes, and divided by 4. You can also try to use Java 'long' type, that corresponds to C's '__int64'.

Then, if the buffer size is a constant, or is never exceeds some limit (as far as I can understand, 32Kb), you may use the single instance of Argument for sending and receiving data:

Pointer srb_bufpointer = (Pointer)Argument.create("int*", buf);

foo1.invoke(srb_bufpointer); //use for sending

foo2.invoke(srb_bufpointer); //use for receiving

int[] arr = (int[])srb_bufpointer.createArray(length);

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×