
本文介绍在 ojAlgo 库中对 Primitive64Matrix(新版为 MatrixR064)或可变矩阵 Primitive64Store 的每一行进行高效排序的正确实践,避免低效拷贝,推荐使用 RowView + ArrayR064 缓冲区的组合方式。
本文介绍在 ojalgo 库中对 `primitive64matrix`(新版为 `matrixr064`)或可变矩阵 `primitive64store` 的每一行进行高效排序的正确实践,避免低效拷贝,推荐使用 `rowview` + `arrayr064` 缓冲区的组合方式。
在 ojAlgo 中,Primitive64Matrix(在 v48+ 已重命名为 MatrixR064)是不可变(immutable)矩阵类型——这意味着任何“修改”操作(如替换某一行)都必须通过创建新实例完成,无法原地更新。你当前代码中反复调用 .copy() 并重建矩阵,不仅语义冗余,而且性能开销显著(每次 .copy() 都会复制整个矩阵数据)。幸运的是,ojAlgo 提供了更高效、更符合设计意图的替代方案。
✅ 推荐方案一:使用 MatrixR064 + DenseReceiver(适用于不可变场景)
若必须使用不可变矩阵(例如需保持函数式风格或兼容旧接口),应一次性构建接收器(DenseReceiver)并批量填充,而非循环中多次 .copy():
double[][] tab = { { 1, 3, 4, 2 }, { 0, 4, 3, 1 } };
MatrixR064 matrix = MatrixR064.FACTORY.rows(tab);
// 一次性创建接收器,避免循环内重复 copy
DenseReceiver receiver = matrix.copy();
ArrayR064 temp = ArrayR064.make(matrix.getColDim()); // 复用缓冲区
for (RowView<double> rowView : matrix.rows()) {
rowView.supplyTo(temp.data); // 高效提取当前行到数组
Arrays.sort(temp.data); // 原地排序
receiver.fillRow(rowView.row(), temp); // 直接填入目标行
}
matrix = receiver.get(); // 最终一次性获取新矩阵</double>
? 关键优化点:
- rowView.supplyTo(...) 比 matrix.row(i).toRawCopy1D() 更高效(避免中间 Access1D 封装与额外数组分配);
- ArrayR064.make(n) 复用同一缓冲区,减少 GC 压力;
- fillRow(int, ArrayR064) 是专为批量写入优化的 API,比 FACTORY.rows(...) 构造再赋值快得多。
✅ 推荐方案二:改用 Primitive64Store(推荐!支持真正原地修改)
Primitive64Store 是可变(mutable)的底层存储实现,无需拷贝即可直接修改,语义清晰且性能最优:
double[][] tab = { { 1, 3, 4, 2 }, { 0, 4, 3, 1 } };
Primitive64Store matrix = Primitive64Store.FACTORY.rows(tab); // 返回可变 store
ArrayR064 temp = ArrayR064.make(matrix.getColDim());
for (RowView<double> rowView : matrix.rows()) {
rowView.supplyTo(temp.data);
Arrays.sort(temp.data);
matrix.fillRow(rowView.row(), temp); // 直接写回原矩阵,无拷贝!
}
// matrix 已就地更新,无需 reassign</double>
✅ 这是最简洁、最高性能的解法:零对象分配(除 temp 外)、无中间矩阵、逻辑直白。Primitive64Store 是 ojAlgo 推荐用于计算密集型场景的默认存储类型。
⚠️ 注意事项与最佳实践
- 不要混淆类型:MatrixR064(不可变) vs Primitive64Store(可变)。优先选用后者处理需修改的矩阵;
- 避免 toRawCopy1D():它创建新数组且绕过 ojAlgo 内部优化,RowView.supplyTo() 是标准高效提取方式;
- 复用 ArrayR064:其 data 字段是 double[],可安全复用,避免每行新建数组;
- 版本兼容性:若使用 ojAlgo ≥ v48,请将 Primitive64Matrix 替换为 MatrixR064,Primitive64Store 名称保持不变;
- 扩展性提示:如需按列排序或自定义比较器,可结合 ColumnView 或 Arrays.sort(double[], from, to, comparator)(需自行索引映射)。
总之,放弃“先取行→排序→构造新行→替换”的链式思维,转向 ojAlgo 的视图(RowView)+ 存储(Store)+ 缓冲(ArrayR064)三位一体模式,即可写出既高效又地道的矩阵行排序代码。











