如何高效对ojAlgo的Primitive64Matrix每行排序及填充行?
高效操作ojAlgo Primitive64Matrix的行排序与填充
核心优化点
你当前实现的效率瓶颈在于每次循环都复制整个矩阵。ojAlgo提供了直接操作矩阵底层数据的方式,完全可以避免这种无意义的全量复制。
1. 高效行排序(原地修改)
用Primitive64Matrix.FACTORY.rows()创建的矩阵本质是Primitive64Matrix.DenseStore,可以通过可变视图或直接操作底层数据完成行排序:
方案一:通过可变视图直接修改
final double[][] tab = { {1, 3, 4, 2}, {0, 4, 3, 1} }; Primitive64Matrix matrix = Primitive64Matrix.FACTORY.rows(tab); int columnCount = matrix.countColumns(); // 获取矩阵的可变视图,直接在原数据上修改 Primitive64Matrix.Mutable mutableMatrix = matrix.mutable(); for (int iRow = 0; iRow < matrix.countRows(); iRow++) { double[] rowData = new double[columnCount]; // 提取当前行数据到数组 matrix.row(iRow).copyTo(rowData); // 排序 Arrays.sort(rowData); // 直接写回原矩阵对应行,无需复制整个矩阵 mutableMatrix.fillRow(iRow, rowData); } // 若需要不可变矩阵,可转换回去 // matrix = mutableMatrix.immutable();
方案二:行优先存储下的极致优化
ojAlgo默认是列优先存储,行元素在底层数组中不连续。如果场景允许,可创建行优先存储的矩阵,直接对底层数组的区间排序,效率最高:
// 创建行优先存储的矩阵工厂 Primitive64Matrix.Factory rowMajorFactory = Primitive64Matrix.FACTORY.with(StorageConstants.RAW); Primitive64Matrix.DenseStore matrix = rowMajorFactory.rows(tab); double[] rawData = matrix.data; int rowLength = matrix.countColumns(); for (int iRow = 0; iRow < matrix.countRows(); iRow++) { int start = iRow * rowLength; int end = start + rowLength; // 直接对底层数组的行区间排序,无需提取临时数组 Arrays.sort(rawData, start, end); }
2. 高效填充矩阵行
填充行的高效方式分几种场景:
- 从数组填充:直接调用
mutableMatrix.fillRow(rowIndex, doubleArray),无需创建临时矩阵 - 从其他矩阵的行填充:
mutableMatrix.fillRow(targetRow, sourceMatrix.row(sourceRow)) - 自定义规则填充:通过
mutableMatrix.set(rowIndex, colIndex, value)逐个赋值,适合复杂生成逻辑
内容的提问来源于stack exchange,提问作者user642308
相关产品推荐
相关产品推荐

