You can use parallel
stream to reduce the computation time by about half. For example, combinations of three double[]
arrays of 300 elements:
/**
* @param arrays an arbitrary number of arrays.
* @return the Cartesian product of the passed arrays.
*/
public static double[][] parallelCombinations(double[]... arrays) {
return Arrays.stream(arrays)
// represent each array element as a single element array
.map(arr -> Arrays.stream(arr).mapToObj(d -> new double[]{d})
// Stream<double[][]>
.toArray(double[][]::new))
// summation of pairs of inner arrays in parallel
.reduce((arr1, arr2) -> Arrays.stream(arr1)
// comment this line to check the sequential stream
.parallel()
// combinations of inner arrays
.flatMap(inner1 -> Arrays.stream(arr2)
// merge two inner arrays into one
.map(inner2 -> Stream.of(inner1, inner2)
.flatMapToDouble(Arrays::stream)
.toArray()))
// array of combinations
.toArray(double[][]::new))
// otherwise an empty 2d array
.orElse(new double[][]{});
}
// test
public static void main(String[] args) {
// size of arrays
int size = 300;
// prepare arrays
double[] arr1 = doubleArray(0, size);
double[] arr2 = doubleArray(size, size);
double[] arr3 = doubleArray(size * 2, size);
long time = System.currentTimeMillis();
// array of combinations
double[][] combinations = parallelCombinations(arr1, arr2, arr3);
// output
System.out.println("Combinations: " + combinations.length);
// Combinations: 27000000
System.out.println(System.currentTimeMillis() - time);
// with .parallel() the time is - 10321
// without .parallel() the time is - 23468
}
public static double[] doubleArray(int from, int size) {
// sequentially filled array of doubles
return DoubleStream.iterate(from / 10.0, d -> d + 0.1).limit(size).toArray();
}
See also: Parallelized Matrix Multiplication