java 流读取double_java – 用于转置double [] [] Matrix的紧凑流表...

本文介绍了如何使用Java Stream高效地转置double类型的二维数组,并通过基准测试对比了for循环、普通Stream及并行Stream的性能差异。结果显示,对于大矩阵,平行Stream解决方案在性能上更优。
摘要由CSDN通过智能技术生成

你可以有:

public static UnaryOperator transpose() {

return m -> {

return range(0, m[0].length).mapToObj(r ->

range(0, m.length).mapToDouble(c -> m[c][r]).toArray()

).toArray(double[][]::new);

};

}

此代码不使用forEach,但更喜欢使用mapToObj和mapToDouble将每一行映射到它们的转置.我还改变了函数< double [] [],double [] []>到UnaryOperator< double [] []>因为返回类型是相同的.

但是,在assylias的答案中使用简单的for循环可能效率不高.

示例代码:

public static void main(String[] args) {

double[][] m = { { 2, 3 }, { 1, 2 }, { -1, 1 } };

double[][] tm = transpose().apply(m);

System.out.println(Arrays.deepToString(tm)); // prints [[2.0, 1.0, -1.0], [3.0, 2.0, 1.0]]

}

我已经实现了一个JMH基准测试,比较上面的代码,for循环版本,以及上面的代码并行运行.使用大小为100,1000和3000的随机平方矩阵调用所有三种方法.结果是对于小矩阵,for循环版本更快但是对于更大的矩阵,并行Stream解决方案在性能方面确实更好(Windows 10, JDK 1.8.0_66,i5-3230M @ 2.60 GHz):

Benchmark (matrixSize) Mode Cnt Score Error Units

StreamTest.forLoopTranspose 100 avgt 30 0,026 ± 0,001 ms/op

StreamTest.forLoopTranspose 1000 avgt 30 14,653 ± 0,205 ms/op

StreamTest.forLoopTranspose 3000 avgt 30 222,212 ± 11,449 ms/op

StreamTest.parallelStreamTranspose 100 avgt 30 0,113 ± 0,007 ms/op

StreamTest.parallelStreamTranspose 1000 avgt 30 7,960 ± 0,207 ms/op

StreamTest.parallelStreamTranspose 3000 avgt 30 122,587 ± 7,100 ms/op

StreamTest.streamTranspose 100 avgt 30 0,040 ± 0,003 ms/op

StreamTest.streamTranspose 1000 avgt 30 14,059 ± 0,444 ms/op

StreamTest.streamTranspose 3000 avgt 30 216,741 ± 5,738 ms/op

基准代码:

@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)

@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)

@BenchmarkMode(Mode.AverageTime)

@OutputTimeUnit(TimeUnit.MILLISECONDS)

@Fork(3)

public class StreamTest {

private static final UnaryOperator streamTranspose() {

return m -> {

return range(0, m[0].length).mapToObj(r ->

range(0, m.length).mapToDouble(c -> m[c][r]).toArray()

).toArray(double[][]::new);

};

}

private static final UnaryOperator parallelStreamTranspose() {

return m -> {

return range(0, m[0].length).parallel().mapToObj(r ->

range(0, m.length).parallel().mapToDouble(c -> m[c][r]).toArray()

).toArray(double[][]::new);

};

}

private static final Function forLoopTranspose() {

return m -> {

final int rows = m.length;

final int columns = m[0].length;

double[][] transpose = new double[columns][rows];

for (int r = 0; r < rows; r++)

for (int c = 0; c < columns; c++)

transpose[c][r] = m[r][c];

return transpose;

};

}

@State(Scope.Benchmark)

public static class MatrixContainer {

@Param({ "100", "1000", "3000" })

private int matrixSize;

private double[][] matrix;

@Setup(Level.Iteration)

public void setUp() {

ThreadLocalRandom random = ThreadLocalRandom.current();

matrix = random.doubles(matrixSize).mapToObj(i -> random.doubles(matrixSize).toArray()).toArray(double[][]::new);

}

}

@Benchmark

public double[][] streamTranspose(MatrixContainer c) {

return streamTranspose().apply(c.matrix);

}

@Benchmark

public double[][] parallelStreamTranspose(MatrixContainer c) {

return parallelStreamTranspose().apply(c.matrix);

}

@Benchmark

public double[][] forLoopTranspose(MatrixContainer c) {

return forLoopTranspose().apply(c.matrix);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值