高效/并行将操作应用于Java中的每个元素< = 1.7?

时间:2015-10-14 09:19:25

标签: arrays multidimensional-array parallel-processing java-7 vectorization

我对将操作(独立地)应用于Java Array中的每个元素感兴趣。例如,将数值数组的每个元素裁剪为不超过给定元素。

示例:

myArray.clip(5)

或者

Utils.clip(myArray, 5)

将每个大于5的元素设置为5

最直接的方法是迭代元素,但我不喜欢它有两个原因:

  • 这是迭代的,并没有利用并行机会
  • 代码看起来不漂亮,映射或编辑语法会更好

我需要进行大约5000次这样的剪切操作,每次都是70 X 10(2D阵列)

如果Java< = 1.7并未提供在标准库中执行此操作的方法。如何使用其他库或Java 1.8功能实现我想要的(上面两点)。

3 个答案:

答案 0 :(得分:1)

用于并行处理集合中数据的传统Java 7技术是" fork / join"图案。这个概念是一个人将要完成的工作分解成更小的部分,分离任务来完成这些部分,然后在最后加入每个任务。

但是,我不确定你的情况是否适用于此。取决于" clip"的复杂程度。操作是,创建一对螺纹以同时在两个轴上操作可能更直接。但是,我可能会误解你的要求。

另一种解决方案可能是时间/空间权衡。在更新主集合时维护剪辑版本的数据可能更有用。生产者 - 消费者模型的排序,其中有一些东西可以查找集合的变化,并维护一个剪裁版本。

答案 1 :(得分:0)

我不确定Arrays本身,但是如果你有一个“Collection”兼容类型,你可以在Java 8中使用并行聚合操作。

请参阅https://docs.oracle.com/javase/tutorial/collections/streams/index.html

答案 2 :(得分:0)

使用Java 8功能,我就是这样做的,我迭代了行并对其进行了并行操作。我没有找到任何采用

的标准方法
double [] []

并将其用作流或

parallelSetAll(double [] [] ...)

我的代码,我使用Apache commons-math库进行矩阵实现,因为它提供了基于库中实现的RealMatrix类型的实用函数

这段代码可以进一步优化,而不必太过分。比如从for循环中取出或稍后进行分配等等

public static RealMatrix clipLower(RealMatrix m, double lowerBound){
        // TODO see if you really need to modify m or just return a modified copy of m

        //process the matrix row by row, each row gets processed in parallel
        // TODO See if you can directly parallelize on the entire matrix not row by row
        // OPEN implement using Arrays.parallelSetAll Method?
        int nrOfRows = m.getRowDimension();

        for(int i = 0; i < nrOfRows; i++){
            // TODO move the declaration outside the for loop
            double[] currRow = m.getRow(i);
            double[] newRow  = Arrays.stream(currRow)
                                     .parallel()
                                     .map((number) -> (number < lowerBound) ? lowerBound : number)
                                     .toArray();
            m.setRow(i, newRow);
        }

        return m;
    }