【问题标题】:Efficient way to insert a value into an array?将值插入数组的有效方法?
【发布时间】:2012-01-18 22:01:57
【问题描述】:

我需要在数组中插入一个值...理想情况下,我可以从 List<myObj> 开始,但我需要使用的方法返回 myObj[]。

我总是需要在第一个位置插入一个值,而不是蠕虫已经在数组中的值...我想出了以下方案..

    List<myObj> list = array.ToList<myObj>();
        if (list.Count > 0 && list != null)
        {
            list.Insert(0, InsertRecord(myParam)); // InsertRecord() is one of my methods...
        }
        return list.ToArray();

我的问题是……这甚至是远程有效的吗?有没有更好的方法来做我需要完成的事情?

【问题讨论】:

  • 你真正想在这里做什么?您如何阅读列表?随机?第一项?最后一项?枚举整个列表?
  • @AndrewBarber: ToList 实际上并没有创建数组的副本,它使用 List&lt;T&gt; 构造函数,该构造函数接受 IEnumerable&lt;T&gt; 并将其包装。
  • @EdS。我实际上的意思是他的 ToArray() 最后调用......哎呀。但是,无论如何,我就在那里吗?
  • @AndrewBarber:是的,那个。它使用 Buffer&lt;T&gt; 并且 Buffer 构造函数执行复制。
  • 您需要return 一个数组还是consume 一个数组(或两者)?

标签: c# arrays performance


【解决方案1】:

我认为你可以节省一些时间

var newArray = new myObj[oldArray.Length  + 1];    
oldArray.CopyTo(newArray, 1);
newArray[0] = InsertRecord(myParam);

【讨论】:

  • 在您需要返回一个数组之前使用列表并不比像他那样调用ToArray 更好。因为 List Add 只有在达到容量时才为 o(n)。
  • 我认为它仍然具有相同的界限,即使是一个可能更好的挂钟。 (假设 Insert 是 O(1) amortized 并且副本是 O(n) 并且在需要它作为数组之间只添加了一项。)
  • 这里没有办法避免 O(n) 复制。这个答案只是针对最低的开销。通过List&lt;&gt; 只是增加了很多步骤。
  • @Magnus 视情况而定,看起来 OP 是偶尔添加的,所以 Henk 更好,但如果连续插入多个插入,效率会更高。
  • @firthh 这似乎微不足道,但我只需要插入到数组的第一个位置,我只需要执行一次。既然是这样,将数组的大小增加 1 确实有意义
【解决方案2】:

List&lt;T&gt; 类由数组支持,因此使用 List 在索引 0 处插入和使用数组在索引 0 处插入在性能上没有区别,除了 BCL 开发人员进行了更广泛的测试为了表现。不要承受ToList 方法和List&lt;T&gt; 构造函数的性能损失,因为无论如何都会在幕后进行新的数组分配。

更糟糕的是,您发布的代码可能需要 两个 数组分配,因为 List&lt;T&gt; 构造函数(由 ToList 调用)可能会分配一个与 array 大小完全相同的数组,然后Add 方法必须分配一个新数组才能执行插入。不太可能,但可能。

简而言之,自己分配新数组。

编辑:

鉴于您的方法需要返回一个数组,遍历一个列表根本没有任何意义。使用列表,您将原始数组复制到支持List&lt;T&gt; 的数组中,然后插入,然后将该支持数组复制到另一个数组中以从您的方法返回。这使得两个数组分配最少,加上我上面提到的可能的第三个。使用原始数组可以保证只分配一个数组。

【讨论】:

    猜你喜欢
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2016-02-03
    • 1970-01-01
    相关资源
    最近更新 更多