栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

用于转换double [] []矩阵的紧凑流表达式

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

用于转换double [] []矩阵的紧凑流表达式

你可以有:

public static UnaryOperator<double[][]> 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
每行映射到它们的转置。由于返回类型相同,因此我也更改
Function<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  UnitsStreamTest.forLoopTranspose       100  avgt   30    0,026 ±  0,001  ms/opStreamTest.forLoopTranspose      1000  avgt   30   14,653 ±  0,205  ms/opStreamTest.forLoopTranspose      3000  avgt   30  222,212 ± 11,449  ms/opStreamTest.parallelStreamTranspose100  avgt   30    0,113 ±  0,007  ms/opStreamTest.parallelStreamTranspose          1000  avgt   30    7,960 ±  0,207  ms/opStreamTest.parallelStreamTranspose          3000  avgt   30  122,587 ±  7,100  ms/opStreamTest.streamTranspose        100  avgt   30    0,040 ±  0,003  ms/opStreamTest.streamTranspose       1000  avgt   30   14,059 ±  0,444  ms/opStreamTest.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<double[][]> 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<double[][]> 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<double[][], double[][]> 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);    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/515475.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号