您要实现的基本上是矩阵转置,然后将数据写入文件。
转置矩阵的最有效方法是什么是一个复杂的问题,实际上取决于您的架构。
如果您并不真正关心为您的处理器(或加速器)进行超级优化,我会选择一个简单的嵌套 for 循环,在中间内存表示中累积数据:
string[] lines = new string[NN[0].Count]; // assume all lines have equal length
for(int i = 0; i < NN.Count; ++i) {
for(int j = 0; j < NN[i].Count; ++j) {
lines[j] += NN[i][j] + ((i==NN.Count - 1) ? "" : ",");
}
}
File.WriteAllLines("path.csv", lines);
作为第一次优化,我不建议使用列表列表,因为访问元素会非常密集。 二维数组会做得更好。
int[,] NN = new int[3,6] {{1, 2, 3, 4, 5, 6 }, {2, 5, 6, 3, 1, 0}, {0, 9, 2, 6, 7, 8}};
string[] lines = new string[NN.GetLength(1)];
for (int i = 0; i < NN.GetLength(0); ++i)
{
for (int j = 0; j < NN.GetLength(1); ++j)
{
lines[j] += NN[i,j] + ((i == NN.GetLength(0) - 1) ? "" : ",");
}
}
File.WriteAllLines("path.csv", lines);
这是一个性能测试,针对 500x500 元素(不包括写入文件):
为了改进这个解决方案,我首先在内存中进行转置(不向文件或字符串写入任何内容),然后执行 join(,) 并写入文件(作为单字节数组)。
如果你想进一步优化,想想总是有空间的:)
例如,在 x86 上,根据您拥有的指令集,您可以读取this article。在启用 CUDA 的设备上,您可以阅读 that。
无论如何,一个好的解决方案总是涉及对齐的内存、子块和接近金属的编写代码(内在或汇编)。