【问题标题】:C# arrays with unknown size未知大小的 C# 数组
【发布时间】:2013-01-03 20:13:00
【问题描述】:

我需要里面有数组的类:

class FirstClass
{
     int x = 0;
     int y = 0;
}

class SecondClass
{
    FirstClass[] firstclass = ???????? // size of array is unknown
    OtherClass[][] otherclass = ???????? // i need also multidimensional array or array of arrays
}

通常我将List<> 用于这样的目的,但今天我需要最快的解决方案(要处理大量数据),我认为 Array 应该比 List 更快(我在某处读过 List 很多比数组慢)。

问题是 - 将什么放入“?????????”在我的代码中?

编辑:

我的班级是一个神经网络对象。最大的数组将包含学习数据(100000+ 数据行,50+ 字段,浮点或双精度数据类型)。

如果 Array 比 List 快 1% - 我需要 Array。

【问题讨论】:

  • ???????? = new List<FirstClass>(expectedCapacity)
  • 您是否已经使用列表构建了它,但发现它太慢了?您是否有任何证据表明列表部分会成为瓶颈?如果不是,这是过早的优化。
  • 这取决于你所说的“过程”是什么意思。
  • 你能再澄清一下你的意图吗?为什么你认为数组会比列表更好的解决方案?你打算做什么?

标签: c# .net-3.5


【解决方案1】:

在知道数组的确切大小之前,您不能创建数组:与列表不同,数组不能增长*;一旦你给他们一个尺寸,他们就会永远保持这个尺寸。如果你必须有一个数组来处理,先创建一个List<T>,填充它,然后用ToArray()方法转换成数组:

var firstClassList = new List<FirstClass>();
firtstClassList.Add(new FirstClass(123));
firtstClassList.Add(new FirstClass(456));
FirstClass firstClass[] = firtstClassList.ToArray();

var otherClassList = new List<List<OtherClass>>();
otherClassList.Add(new List<OtherClass>());
otherClassList[0].Add(OtherClass(10));
otherClassList[0].Add(OtherClass(11));
otherClassList.Add(new List<OtherClass>());
otherClassList[1].Add(OtherClass(20));
otherClassList[1].Add(OtherClass(21));
otherClassList[1].Add(OtherClass(22));
OtherClass otherClass[][] = otherClassList.Select(r => r.ToArray()).ToArray();

但是请注意,这是过早的优化:列表与数组一样快,但它们提供了更多的灵活性。用数组替换列表没有意义,至少在你分析之前没有。


* 调用Array.Resize 来更改数组的大小不算作“增长”数组,因为您最终会得到一个不同的数组实例,而您正试图“增长”复制后立即被丢弃。

【讨论】:

  • .NET 中有一种调整数组大小的方法(它可能会重新分配内存)。我暂时使用它,可能会留下它。
  • @Kamil Array.Resize documentation 明确表示数组被重新分配——无论是在大小增加时,还是在大小减小时。无论如何,它并不比List&lt;T&gt; 更有效。
  • 您正确的数组在技术上无法调整大小,但您可以使用 Array.Resize 方法返回指定大小的新数组msdn.microsoft.com/en-us/library/bb348051.aspx
  • 很抱歉,我在点击提交后几乎立即意识到自己的错误。
  • @Kamil 递增 1000 将使您的渐近性能比 List 更差:如果有 4000 万个项目,您的策略将重新分配 40,000 次,而 List 将重新分配少于 25 次。你不太可能击败List,因为微软已经从其实施中榨取了每 1% 的性能。
【解决方案2】:

如果您不确定数组的大小,您可能需要考虑使用不同类型的集合,例如您提到的 List&lt;FirstClass&gt; 或 ArrayList 等。

在性能方面,在您实际测试数据之前,使用 List 可能没问题,如果仍然有问题或瓶颈,请考虑使用 Array 或更有效的结构。 (运行时间不应相差太大,除非您处理的是非常大的数据集。)

(总是可以选择将列表转换为数组。)

【讨论】:

    【解决方案3】:

    为什么 Array 会比 List 快? See this question 比较运行时间。

    我能想到的唯一情况是,如果您需要搜索一个元素,并且该数组已排序,因此您可以进行二进制搜索。但是,由于您可以在 C# 中使用 [] 来索引 Lists,因此这是一个有争议的问题。

    【讨论】:

    • stackoverflow.com/questions/454916/… 看起来数组比for 循环中的列表至少快 5%。 5% 对我来说很重要。
    • @Kamil:现在我知道你用它做什么了,这是有道理的。你看过 AForge (code.google.com/p/aforge) 吗?
    • 我看到了 AForge。我在 codeproject 上读过关于它的好文章(由 Andrew Kirillov 撰写)。我想创建自己的神经网络实现并实现多线程。像这样在 AForge 库上升级可能对我来说太复杂了,我有点业余。
    • 他们的源代码中确实有一个示例,其中二维数组不是类级别,而是在实际读取数据时被实例化,例如:int[][] input = new int[sampleSize] [];或类似的东西。这可能比尝试在开始时设置大小更容易,除非您在阅读所有数据之前不知道数据集有多大,在这种情况下,将其放入列表中,然后使用 .ToArray( )。祝NN好运。这是一个有趣的项目。
    【解决方案4】:
    var list = new List<FirstClass>();
    list.Add(object);
    
    FirstClass[] firstClass = list.ToArray();
    
    var listOfLists = new List<List<SecondClass>>();
    var item1 = new List<SecondClass>();
    item1.Add(anotherObject);
    listOfLists.Add(item1);
    
    SecondClass[][] secondClass = listsOfLists.Select(i => i.ToArray()).ToArray();
    

    【讨论】:

      【解决方案5】:

      你可以像这样实例化它们:

      FirstClass[] firstclass = new FirstClass[];
      OtherClass[][] otherclass = new OtherClass[][];
      

      然后在需要添加元素时使用 Add 方法:

      firstclass.Add(new FirstClass());
      

      【讨论】:

      • 这是什么语言?当然,这不是 C#,because in C# this does not compile。
      • 错误:“数组创建必须具有数组大小或数组初始值设定项”。
      • 最好删除它并保存您的声誉:)
      • Kamil 你可以在不声明初始大小的情况下定义一个数组实际上你可以像这样运行示例,你会看到它有效.. string[] variableNames = { };//new string [3]; for(var i = 0; i
      猜你喜欢
      • 1970-01-01
      • 2014-09-14
      • 1970-01-01
      • 2020-11-13
      • 2016-03-03
      • 2014-02-22
      • 2015-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多