
本文介绍在 ojAlgo 库中对 Primitive64Matrix(新版为 MatrixR064)或可变存储 Primitive64Store 的每一行进行原地或高效排序的方法,避免低效的重复拷贝,并提供清晰、可复用的代码示例。
本文介绍在 ojalgo 库中对 `primitive64matrix`(新版为 `matrixr064`)或可变存储 `primitive64store` 的每一行进行原地或高效排序的方法,避免低效的重复拷贝,并提供清晰、可复用的代码示例。
ojAlgo 的 Primitive64Matrix(在 v50+ 中已重命名为 MatrixR064)是不可变(immutable) 矩阵类型——这意味着任何“修改”操作(如替换某一行)都必须通过创建新实例完成,无法直接就地更新。你当前代码中反复调用 .copy() 并重建矩阵,不仅语义冗余,还会带来显著的内存与性能开销。
更优的实践是:优先选用可变存储类型 Primitive64Store(尚未重命名,仍属 org.ojalgo.matrix.store 包),它支持真正的就地填充(fillRow),无需中间拷贝。若必须使用 MatrixR064,也应复用 DenseReceiver 一次性构建结果,而非每行都 .copy()。
以下是两种推荐方案:
✅ 方案一:使用 Primitive64Store(推荐|真正就地排序)
import org.ojalgo.matrix.store.Primitive64Store;
import org.ojalgo.array.ArrayR064;
import org.ojalgo.structure.RowView;
double[][] tab = { { 1, 3, 4, 2 }, { 0, 4, 3, 1 } };
Primitive64Store matrix = Primitive64Store.FACTORY.rows(tab); // 可变存储
// 复用临时数组,避免每行新建
ArrayR064 temp = ArrayR064.make(matrix.getColDim());
for (RowView<Double> rowView : matrix.rows()) {
rowView.supplyTo(temp.data); // 将当前行数据复制到 temp
java.util.Arrays.sort(temp.data); // 原地排序
matrix.fillRow(rowView.row(), temp); // 直接写回该行
}
// 此时 matrix 已被逐行排序,无额外对象分配⚠️ 注意:Primitive64Store 是线程不安全的,多线程环境下需自行同步;但单线程批处理场景下性能最优。
✅ 方案二:使用 MatrixR064(兼容旧代码|单次接收器)
import org.ojalgo.matrix.MatrixR064;
import org.ojalgo.array.ArrayR064;
import org.ojalgo.structure.RowView;
double[][] tab = { { 1, 3, 4, 2 }, { 0, 4, 3, 1 } };
MatrixR064 matrix = MatrixR064.FACTORY.rows(tab);
// 仅创建一次 receiver,避免循环内 copy()
MatrixR064.DenseReceiver receiver = matrix.copy();
ArrayR064 temp = ArrayR064.make(matrix.getColDim());
for (RowView<Double> rowView : matrix.rows()) {
rowView.supplyTo(temp.data);
java.util.Arrays.sort(temp.data);
receiver.fillRow(rowView.row(), temp);
}
matrix = receiver.get(); // 最终获取排序后的新矩阵? 关键要点总结
- 不要对 MatrixR064 调用 .copy() 多次:每次 .copy() 都会深拷贝整个矩阵,O(m×n) 时间与空间开销;
- 优先用 Primitive64Store:它是设计用于计算中间步骤的可变底层存储,fillRow 是 O(n) 操作,无冗余副本;
- 复用 ArrayR064 临时数组:避免在循环中频繁创建/销毁 double[],提升 GC 效率;
- rowView.supplyTo(...) 比 row(...).toRawCopy1D() 更高效:前者直接复制数据,后者可能触发额外封装与拷贝逻辑;
- 若需链式操作(如排序 → 归一化 → 保存),建议全程基于 Primitive64Store 构建 pipeline,最后再转为 MatrixR064 输出。
通过以上方式,你不仅能写出更简洁、专业的 ojAlgo 代码,还能在处理大型矩阵时获得可观的性能提升。

















