有效地将Java列表转换为Matlab矩阵

时间:2014-01-23 15:18:00

标签: java matlab protocol-buffers

我从Matlab调用Google Protocol Buffers Java API。这很好用,但我遇到了很大的性能瓶颈。大部分数据作为以下类型的对象返回:

java.util.Collections$UnmodifiableRandomAccessList

它们实际上包含一个浮动列表。我需要将其转换为Matlab矩阵。到目前为止,我发现的最佳方法是致电:

cell2mat(cell(Q.toArray()))

然而,这一行是代码中的巨大性能瓶颈。

注意我知道Google Protocol Buffers的FarSounder Matlab解析器生成器,遗憾的是这些生成器非常慢。请参阅下文,了解我的问题(YMMV)的一些粗略基准速度。高是好的。

  • Farsounder Matlab:0.03
  • 纯Python:1
  • 从Matlab调用的Java API(仅解析和提取元数据):10
  • 从Matlab调用的Java API(解析和提取元数据和数据):0.25

如果不是为了转换java.util.Collections$UnmodifiableRandomAccessList的开销 对于Matlab矩阵,那么从Matlab调用Java API的方法看起来很有希望。

有没有更好的方法将这个Java对象转换为Matlab矩阵?

请记住,返回此类型的方法是自动生成的代码。

2 个答案:

答案 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()调用(这实际上是否复制?)。