【问题标题】:Fast sum of values in a multidimensional array (C#)多维数组中值的快速求和(C#)
【发布时间】:2010-06-22 12:00:29
【问题描述】:

对于一维数组,我可以使用 sum 方法得到所有值的总和。

int[] array = {6,3,1};
Console.WriteLine(array.Sum());

对于多维数组(在我的例子中是 3D),这是无法做到的。显然我可以全力以赴,但这似乎很冗长,我怀疑它会表现不佳。

有没有办法使数组变平?或者一个很好的方法只是得到我没见过的总和?

【问题讨论】:

  • 你用的是什么版本的VS/dotNET,可以用LinQ吗?
  • @Luke Duddridge 在 prelinq 时代的数组中没有求和

标签: c# arrays multidimensional-array sum


【解决方案1】:

Sum 正好是foreach。他们背后没有魔法。如果您对性能如此渴望,请使用for 而不是foreach。您也可以并行执行此操作,此操作可以轻松并行化。

【讨论】:

  • 也许这应该是一个单独的问题,但我将如何并行化它? (对 C# 很陌生...)
  • 看看这两个链接:msdn.microsoft.com/en-us/magazine/cc163329.aspxblogs.msdn.com/b/pfxteam 特别是在博客上,可以下载一堆样例(ParallelExtensionsExtras)
  • @Tom Wright 它是最著名的并行任务之一,只是谷歌“并行求和计算 C#”的基本思想是将数组划分为多个部分并在并行线程中计算子和。 PLINQ 使它变得更加容易。但在你开始优化某些东西之前,请确保它是实际的瓶颈
  • @Tom Wright - 根据您使用的 C# 版本,您可以使用 Parallel.ForEach:msdn.microsoft.com/en-us/library/…
  • 在使用一维数组时,foreach 最多时会被编译器自动优化为 for 循环,因此不会有性能差异
【解决方案2】:

这样就可以了。

var i = array.SelectMany(j => j).Sum()

你可以像这样在 .net 4 中并行化它

var i = array.AsParallel().SelectMany(k => k).Sum();

【讨论】:

  • 尚未对其进行基准测试,但我认为 array.Sum(j => j.Sum()) 应该更快,并且绝不会降低可读性。 SelectMany().Sum() 必须在数组中移动两次(AFAIK),一次生成新的可枚举,然后再次计算总和(除非 LINQ 对此进行了优化,对此不确定)。
  • sum 和 ienum 因此它将保持一个运行总数并循环遍历它。因此,对于每个 int selectmany 交付,它会将其添加到总数中,因此它只会遍历所有内容一次。但我也没有调查过。
【解决方案3】:

为什么foreach 表现不佳?您必须至少读取每个值一次才能计算总和。没有办法解决这个问题(当然,假设是“随机”值)。所以也许有一种更美观的方式,但没有一种更高效的方式(就Big O而言)。

【讨论】:

  • 我不确定,但根据我看到的一些微基准测试,它们之间可能存在性能差异。
  • @Andrey,bassfriend:你是对的,也许你会得到更高性能的实现,但它们都依赖于循环遍历每一个值。微基准测试和并行化可能会有所帮助,但我的观点是具有 foreach/for 的算法本身的性能并不差。 Linq 或任何不能跳过循环所有值的步骤。
  • 当使用一维数组时,foreach 最多时会被编译器自动优化为 for 循环,因此不会有性能差异
【解决方案4】:

如果你有一个参差不齐的数组并且想要干净的代码,你可以使用

int[][] array = { new []{ 6, 3, 1 }, new []{ 6, 3, 1 } };
Console.WriteLine(array.Sum(i => i.Sum()));

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 2018-02-08
    • 1970-01-01
    • 2015-07-21
    • 2015-10-30
    • 2014-01-16
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    相关资源
    最近更新 更多