I am calling the Google Protocol Buffers Java API from Matlab. This works pretty well, but I have hit a big performance bottleneck. The bulk of the data are returned as objects of type:
java.util.Collections$UnmodifiableRandomAccessList
They actually contain a list of floats. I need to convert this to a Matlab matrix. The best approach I have found so far is to call:
cell2mat(cell(Q.toArray()))
However, that one line is a huge performance bottleneck in the code.
Note I am aware of the FarSounder Matlab parser generators for the Google Protocol Buffers, unfortunately these are very slow. See below for some rough benchmark speeds for my problem (YMMV). High is good.
If it wasn't for the overhead of converting the java.util.Collections$UnmodifiableRandomAccessList
to a Matlab matrix, then the approach of calling the Java API from Matlab would look quite promising.
Is there a better way of converting this Java object into a Matlab matrix?
Bear in mind that the method returning this type is in automatically generated code.
You might be best writing a tiny piece of extra java code, like so:
import java.util.List;
import java.util.ListIterator;
class Helper {
public static float[] toFloatArray(List l) {
float retValue[] = new float[l.size()];
ListIterator iterator = l.listIterator();
for (int idx = 0; idx < retValue.length; ++idx ){
// List had better contain float values,
// or else the following line will ClassCastException.
retValue[idx] = (float) iterator.next();
}
return retValue;
}
}
with which I see:
>> j = java.util.LinkedList;
>> for idx = 1:1e5, j.add(single(idx)); end
>> tic, out = Helper.toFloatArray(j); toc
Elapsed time is 0.006553 seconds.
>> tic, cell2mat(cell(j.toArray)); toc
Elapsed time is 0.305973 seconds.
In my experience, the most performant solution is write a little set of java helpers, that converts the lists to plain arrays of primitive types. These are well mapped to matrices by matlab.
If the above e.g. gives a an array of java.lang.Float
s, the helper could look like this:
public static float[] toFloats(Float[] floats) {
float[] rv = new float[floats.length];
for (int i=0; i < floats.length; i++) rv[i] = (float) floats[i];
return rv;
}
In matlab cell2mat(cell(Q.toArray()))
hence would become:
some.package.toFloats(Q.toArray());
Obviously you could modify the helper function to directly take your list as well, avoiding the need for the toArray()
call (does this actually make a copy?).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With