C#/Linq中的二维数组和

C#/Linq中的二维数组和,linq,plinq,Linq,Plinq,我有一个二维整数数组。我想写一个优化和快速的代码来求二维数组中所有列的和 有没有想过如何使用LINQ/PLINQ/任务并行化来实现这一点 例: 直截了当的LINQ方式: var columnSums = m_indexes.OfType<int>().Select((x,i) => new { x, col = i % m_indexes.GetLength(1) } ) .GroupBy(x => x.col) .Select(x => new {

我有一个二维整数数组。我想写一个优化和快速的代码来求二维数组中所有列的和

有没有想过如何使用LINQ/PLINQ/任务并行化来实现这一点

例:


直截了当的LINQ方式:

var columnSums = m_indexes.OfType<int>().Select((x,i) => new { x, col = i % m_indexes.GetLength(1) } )
    .GroupBy(x => x.col)
    .Select(x => new { Column = x.Key, Sum = x.Sum(g => g.x) });
var columnSums=m_index.OfType()。选择((x,i)=>new{x,col=i%m_index.GetLength(1)})
.GroupBy(x=>x.col)
.Select(x=>new{Column=x.Key,Sum=x.Sum(g=>g.x)});

并行化可能不值得。如果需要按索引访问数组,则需要在边界检查上花费一些周期,因此,与性能一样,一定要测量它。

最简单的并行实现:

 int[,] m_indexes = new int[6, 4]  { {367, 40, 74, 15},
                                     {535, 226, 74, 15}, 
                                     {368, 313, 74, 15},
                                     {197, 316, 74, 15}, 
                                     {27, 226, 74, 15},
                                     {194, 41, 74, 15} };
 var columns  = Enumerable.Range(0, 4);
 int[] sums = new int[4];
 Parallel.ForEach(columns, column => {
     int sum = 0;
     for (int i = 0; i < 6; i++) {
         sum += m_indexes[i, column];
     }
            sums[column] = sum;
 });
如果您确实需要在此处优化性能,请务必在此处对真实数据进行分析


此外,如果您真正关心性能优化,请尝试加载数组,以便跨行求和。通过这种方式,您将获得更好的缓存性能局部性。

或者可能没有for:

List<List<int>> m_indexes = new List<List<int>>()  { new List<int>(){367, 40, 74, 15},
new List<int>(){535, 226, 74, 15}, 
new List<int>(){368, 313, 74, 15},
new List<int>(){197, 316, 74, 15}, 
new List<int>(){27, 226, 74, 15},
new List<int>(){194, 41, 74, 15} };

var res = m_indexes.Select(x => x.Sum()).Sum();
List m_index=new List(){new List(){367,40,74,15},
新列表(){535226,74,15},
新列表(){368313,74,15},
新列表(){197316,74,15},
新列表(){27,226,74,15},
新名单{194,41,74,15};
var res=m_索引。选择(x=>x.Sum()).Sum();

很多想法,请更具体一些。在实际示例中。。。数组的大小为int[60350]。我需要对所有列求和,然后将几个列组合在一起,以找到这些列总数中的最小值和最大值。您是否熟悉
并行。对于
?Gabe-不熟悉将并行。对于。我看到Jason给出了Parallel.Foreach和Linq的例子。继续基准测试并进一步探索实现。谢谢大家。您可以使用
Parallel.For(0,4,…)而不是
Parallel.ForEach(Enumerable.Range(0,4),…)
。这为优化提供了更多的机会,因为列的数量在一开始就知道了(对OP来说),但在使用它之前应该对其进行基准测试:-)对于小型阵列,同步线程所花费的时间通常>您获得的时间。
var columns=Enumerable.Range(0,4)可以是
var columns=Enumerable.Range(0,m_index.GetLength(1))可扩展性。谢谢Jason。我们将探讨实现和基准。我们将据此执行。再次感谢。@Chili Manku:请阅读我刚刚编辑的最后一段。抖动很可能会优化边界检查。
var sums = columns.Select(
    column => {
        int sum = 0;
        for (int i = 0; i < 6; i++) {
            sum += m_indexes[i, column];
         } return sum; 
    }
).ToArray();
List<List<int>> m_indexes = new List<List<int>>()  { new List<int>(){367, 40, 74, 15},
new List<int>(){535, 226, 74, 15}, 
new List<int>(){368, 313, 74, 15},
new List<int>(){197, 316, 74, 15}, 
new List<int>(){27, 226, 74, 15},
new List<int>(){194, 41, 74, 15} };

var res = m_indexes.Select(x => x.Sum()).Sum();