Java列表到Matlab矩阵的高效转换
我从Matlab调用googleprotocolbuffersjavaapi。这很有效,但我遇到了一个很大的性能瓶颈。大部分数据作为以下类型的对象返回:Java列表到Matlab矩阵的高效转换,java,matlab,protocol-buffers,Java,Matlab,Protocol Buffers,我从Matlab调用googleprotocolbuffersjavaapi。这很有效,但我遇到了一个很大的性能瓶颈。大部分数据作为以下类型的对象返回: java.util.Collections$UnmodifiableRandomAccessList 它们实际上包含一个浮动列表。我需要把它转换成Matlab矩阵。到目前为止,我发现最好的方法是: cell2mat(cell(Q.toArray())) 然而,这一行是代码中的一个巨大性能瓶颈 注意,我知道FarSounder Matlab解
java.util.Collections$UnmodifiableRandomAccessList
它们实际上包含一个浮动列表。我需要把它转换成Matlab矩阵。到目前为止,我发现最好的方法是:
cell2mat(cell(Q.toArray()))
然而,这一行是代码中的一个巨大性能瓶颈
注意,我知道FarSounder Matlab解析器生成器用于Google协议缓冲区,不幸的是它们非常慢。关于我的问题(YMMV)的一些粗略基准速度,请参见下文。高是好的
- 法拉第发声器Matlab:0.03
- 纯Python:1
- 从Matlab调用Java API(仅解析和提取元数据):10
- 从Matlab调用的Java API(解析和提取元数据和数据):0.25
java.util.Collections$UnmodifiableRandomAccessList的开销
对于Matlab矩阵,那么从Matlab调用JavaAPI的方法看起来很有前途
有没有更好的方法将此Java对象转换为Matlab矩阵?
请记住,返回此类型的方法是自动生成的代码。您最好编写一小段额外的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;
}
}
根据我的经验,最有效的解决方案是编写一组java助手,将列表转换为原语类型的普通数组。 这些都通过matlab很好地映射到矩阵 如果上面的示例给出了一个
java.lang.Float
s数组,则助手可能如下所示:
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;
}
显然,您也可以修改helper函数来直接获取列表,从而避免调用
toArray()
调用(这实际上是一个副本吗?)我的建议是尽可能减少调用MATLAB Java桥的次数。例如,假设您从MATLAB循环中调用Java代码,而不是收集Java代码中的所有输出,然后从MATLAB中调用此方法。你能分享一些最简单的代码供我们测试吗(我知道Java代码是自动生成的)?这很好。使用这种方法,基准速度0.25现在已增加到6。这使得从Matlab调用javaapi成为迄今为止我尝试过的最快的方法。恐怕我没有足够的声望来支持这个答案。
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;
}
some.package.toFloats(Q.toArray());