2

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

有什么想法可以使用 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} };
4

3 回答 3

5

最简单的并行实现:

 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)and m_indexes.GetLength(1))。

林克:

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

如果您确实需要在此处优化性能,请务必在此处分析真实数据。

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

于 2011-09-12T20:30:38.733 回答
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) });

并行化可能不值得。如果您需要按索引访问数组,则需要在边界检查上花费一些周期,因此,一如既往地对性能进行测量。

于 2011-09-12T20:27:04.230 回答
1

或者也许没有 for's :

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();
于 2011-09-12T20:37:24.277 回答