我有一个二维整数数组。我想编写一个优化的快速代码来汇总二维数组的所有列。
有什么想法我可以使用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} };
答案 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();