C#/ Linq中的二维数组和

时间:2011-09-12 20:23:11

标签: linq plinq

我有一个二维整数数组。我想编写一个优化的快速代码来汇总二维数组的所有列。

有什么想法我可以使用LINQ / PLINQ / TASK并行化来做到这一点吗?

例如:

private 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} };

3 个答案:

答案 0 :(得分:4)

最简单的并行实现:

 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;
 });

此代码显然可以“一般化”(使用m_indexes.GetLength(0)m_indexes.GetLength(1))。

LINQ:

var sums = columns.Select(
    column => {
        int sum = 0;
        for (int i = 0; i < 6; i++) {
            sum += m_indexes[i, column];
         } return sum; 
    }
).ToArray();

如果您真的需要在此优化效果,请务必在此处对实际数据进行

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

答案 1 :(得分:1)

直截了当的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) });

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

答案 2 :(得分:1)

或者可能没有用于:

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();