我从Matlab调用Google Protocol Buffers Java API。这很好用,但我遇到了很大的性能瓶颈。大部分数据作为以下类型的对象返回:
java.util.Collections$UnmodifiableRandomAccessList
它们实际上包含一个浮动列表。我需要将其转换为Matlab矩阵。到目前为止,我发现的最佳方法是致电:
cell2mat(cell(Q.toArray()))
然而,这一行是代码中的巨大性能瓶颈。
注意我知道Google Protocol Buffers的FarSounder Matlab解析器生成器,遗憾的是这些生成器非常慢。请参阅下文,了解我的问题(YMMV)的一些粗略基准速度。高是好的。
如果不是为了转换java.util.Collections$UnmodifiableRandomAccessList
的开销
对于Matlab矩阵,那么从Matlab调用Java API的方法看起来很有希望。
有没有更好的方法将这个Java对象转换为Matlab矩阵?
请记住,返回此类型的方法是自动生成的代码。
答案 0 :(得分:7)
你可能最好编写一小段额外的java代码,如下所示:
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;
}
}
我看到了:
>> 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.
答案 1 :(得分:1)
根据我的经验,最高性能的解决方案是编写一些java助手,将列表转换为原始类型的普通数组。 这些通过matlab很好地映射到矩阵。
如果上述例如给出一个java.lang.Float
的数组,帮助器看起来像这样:
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;
}
在matlab中cell2mat(cell(Q.toArray()))
因此会变成:
some.package.toFloats(Q.toArray());
显然你可以修改辅助函数来直接获取你的列表,避免需要toArray()
调用(这实际上是否复制?)。