在C#中高效地从二维数组中提取向量

5

我有一个非常大的二维数组,需要在这个数组上进行向量操作。NTerms和NDocs都是非常大的整数。

var myMat = new double[NTerms, NDocs];

我需要从这个矩阵中提取向量列。目前,我正在使用for循环。

            col = 100;
            for (int i = 0; i < NTerms; i++)
            {
                myVec[i] = myMat[i, col];
            }

这个操作非常缓慢。在Matlab中,我可以不需要迭代就提取向量,如下所示:

myVec = myMat[:,col];

有没有在C#中实现这个的方法?


你是否有可能在创建时转置 myMat?这样,你提取的是行而不是列,这更加缓存一致并且应该更快(虽然我不知道速度会快多少)。另一个选项是使用 Marshal.Copy 复制内存。此外,你可以尝试使用 Parallel.For 并行化。 - Nico Schertler
1
如果你喜欢使用Matlab,那么你可能会对从C#调用Matlab感兴趣,例如请参考https://dev59.com/ym025IYBdhLWcg3wnXWg。稍微搜索一下就可以得到几个结果。 - Dennis Jaheruddin
2个回答

5
在C#中,没有类似Matlab的构造方式可以让您处理数组。使用您已经拥有的代码,您可以通过Task Parallel Library来加速向量创建过程,该库是在.NET Framework 4.0中引入的。
Parallel.For(0, NTerms, i => myVec[i] = myMat[i, col]);

如果你的CPU有多个核心,那么性能会有所提高,否则没有影响。

如果想了解如何使用任务并行库处理矩阵和数组的更多示例,请参考MSDN文章矩阵分解

但是我怀疑在涉及一些严肃的数学计算时,C#不是一个好的选择。


0

一些可能的问题:

可能是在C#中访问多维数组元素的方式有问题。请参阅此前的文章

另一个问题可能是您正在访问非连续的内存 - 因此缓存帮助不大,如果数组非常大,甚至可能需要从虚拟内存(磁盘)中获取。

当您一次访问整行而不是一列时,速度会发生什么变化?如果显着更快,则可以确定90%是连续内存问题...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接