多维数组 - 获得与1维数组相同的编码能力

时间:2014-06-03 17:10:25

标签: .net arrays

我主要使用C#编程,但这似乎适用于所有.NET。

我处于使用多维数组似乎最合乎逻辑的情况,但我觉得我已经被使用它们锁定了.NET的强大功能。

  • System.LINQ不适用于多维数组。 (ETA:但请参阅Nico Schertler的评论)
  • System.Array的实用程序方法在使用多维数组时非常有限。
  • 似乎没有办法为多维数组编写扩展方法。(ETA:这是错误的,请参阅Nico Schertler的评论)
  • 几年前,多维数组的速度要慢得多 - 这种情况仍然如此吗? Why are multi-dimensional arrays in .NET slower than normal arrays?(ETA:是的,见Tim S'

我知道我可以选择使用扁平数组,但这并不能真正匹配数据。我也知道我可以选择循环遍历所有维度和复制,但是当语言和编译器是智能的时候,这似乎是一种古老的做法。所以我的问题是:

  • 是否有一种标准方法可以将LINQ(或等效功能)与多维数组一起使用(将二维数组转换为数据库或List<Tuple>)?
  • 是否有标准的方法来切割多维数组(返回单个超曲面或一系列超曲面)?
  • 排序。我找到了C# rectangular array sort;但这并不适用,因为我事先知道尺寸。

ETA:我特别谈到&#34;本地人&#34;在C#中声明double[,] dataTable = new double[5,3];的数组类型,而不是锯齿状数组,或任何其他嵌套类。

4 个答案:

答案 0 :(得分:2)

他们是非常笨拙的数据结构。在任何语言中,不仅仅是C#。他们的一些固有问题:

  • 没有有意义的方法来迭代它们。顺序本质上是模糊的,没有办法表明新维度开始迭代。这就是杀死它们在Linq中使用的原因。
  • 计算元素的地址本身就很昂贵。 N维数组需要N-1次乘法和N次长度查找和绑定检查才能找到元素
  • 他们方式易于使用错误,按照使用CPU缓存的顺序访问元素非常差
  • 向量在CLR中获得了很多优化爱,多维数组没有,因为获得的收益很少
  • 当然,由于索引器的数量是可变的,因此Array很笨拙。

所以不要使用它们。锯齿状数组和列表列表是合理的替代方案。减去语法糖,可以说C#太多了。

答案 1 :(得分:1)

  

是的,确实如此。这是使用C#5 / .NET 4.5重新运行该代码,通过LINQPad运行,并进行优化。

sum took 00:00:01.7903305
sum took 00:00:02.9606820 (165%)
sum took 00:00:01.7093106 (95%)

结论有点主观,但我同意你的看法,多维数组是二等公民。在大多数情况下,锯齿状数组(double[][])和列表(List<List<double>>)似乎是首选方法。

有时代码是用锯齿状或多维数组编写的,这些数组从来就不应该像那样开始...例如。 List<MyModel>Dictionary<double, double>可能是更好的选择。

答案 2 :(得分:1)

首先,LINQ旨在处理序列。通常,人们认为序列是一维实体。因此,它对多维数据类型不起作用也就不足为奇了。虽然LINQ可能可以被扭曲以承担行主要顺序和步行多维数组,但这并不是普遍接受的处理事物的方式。即便如此,您仍然可以使LINQ与多维数组配合良好,但不能与列表列表(即List<List<int>>)配合使用。这会打开一大堆蠕虫。总而言之,你可能最好还是编写自己的枚举器,将多维结构转换为一维序列。

一维数组通常比多维数组更快,因为你必须做更少的边界检查。这与锯齿状阵列通常更快的原因相同。但这并不普遍。请参阅我的博客文章Are jagged arrays faster than rectangular arrays?

我认为没有证据表明微软正在推动&#34;我们在多维数组上使用一维数组。一维阵列更简单,因此更容易优化。并且,由于一维阵列的使用频率更高,因此它们会得到更多的关注。

我怀疑许多Array课程的功能不适用于多维数组的原因是因为它们对多个维度没有意义,或者因为它们&# 39;通常不足以保证实施它们的难度。在使用多维数组时,我很少很少需要这些功能。

答案 3 :(得分:0)

我会说不。因为我是一个非常狂热的字典类用户。尤其是字典词典。

是的,由于嵌套而没有,它往往会运行得慢一些。但代码本身往往具有很强的可读性,适合协作。